2017-07-09 3 views
1

したがって、現在の列内容をtable_1列 "table_1_content"とtable_2の別の列(table_2_content)の内容と比較しているSELECT文がありますが、 table_2_contentはtable_1_content 『」内のどこにでも見つけることができます』:Mysql:LIKE CONCAT Replacement - > less performance heavy

$select = "SELECT * FROM table_1, table_2 WHERE `table_1_content` LIKE CONCAT('%', table_2_content, '%')"; 
$result = mysqli_query($con, $select); 

私の問題は、LIKE CONCATはかなりのパフォーマンス重いということです。

異なるテーブルから2つの列を検索する別の方法があります。クエリが実行されるたびにフルテーブルスキャンは実行されません。

+0

'LIKE'述語の先頭にある'% 'は、インデックスの使用を排除します。フルテキスト検索を検討することができます。 –

+2

@TimBiegeleisen FTSは、マッチデータを別のテーブルから取得できないため、リテラルでなければなりません。 – Barmar

答えて

2

LIKEのフリーテキスト形式(検索文字列の先頭と末尾の%)がパフォーマンスの重い部分です。文字列の先頭にワイルドカードが必要ですか?その場合:検索で単一のワイルドカードまたはワイルドカードをまったく使用できないように、データを別の方法で前処理することを検討する必要があります。この最後の部分(データに依存する)は、例えば、文字列を区切り文字で分割し、データを別々の行に格納することによって実行されます。その後、はるかに高速な比較と索引が使用できます。

複数の行にデータを入れるために、我々は、使用可能なセパレーターを引き受ける(複数のことができ、コードは単に長くなります):

CREATE TABLE baseinfo (id INT NOT NULL auto_increment primary key, 
    some other columns); 

CREATE TABLE explodedstring(id INT NOT NULL, str VARCHAR(200), 
    FOREIGN KEY (id) REFERENCES baseinfo(id)); 

CREATE PROCEDURE explodestring(id int, fullstr VARCHAR(4000)) 
BEGIN 
    {many examples exist already how to do this on SO} 
END; 

手順はid(元のデータからの入力として、あなたの鍵を取りますこの場合)、元の文字列を返します。 プロシージャの出力はセカンダリテーブルexplodedstringになります。これに対して、通常のselect(パフォーマンスのためにいくつかのインデックスを追加)を実行できるようになりました。結果として得られるidは、一致するレコードを教えてくれます。

+0

あなたの落雷のお返事ありがとう!私は必要な文字列の数に特定の制限がないので、データを別の行に置くことはできません。複数の行を使用せずに区切り文字で文字列を分割することはできますか、誤解していますか? – Adelol

+0

複数の行メソッドがどのように機能するかを確認するために、答えの更新を(ちょっと)見てください。 –

+0

私はそれを試します。 – Adelol