1

次のクエリがあります。

SELECT * FROM table 
    WHERE tags LIKE '%$search%' 
          AND tags NOT LIKE '% $search%' 
          AND tags NOT LIKE '%$search %'

基本的に、検索用語の前後にスペースがない限り、一致するすべての用語を検索します。

そのため、 を検索して"novel"も、用語"graphic novel"or"novel romantic"は表示されません。

これはコストのかかるクエリのように思えるので、これを行うためのより効率的な方法があるかどうか疑問に思っていました. ありがとう!

4

2 に答える 2

1

正規表現の一致により、クエリが短くなります(よりきれいになるのはオブザーバーの問題です)が、最も効率的ではありません。

Sashi Kantへのコメントを見て、検索しているテキストがコンマで区切られた属性のセットであると推測できますか?あなたが書いた:big,novel,graphic novel。いつもそうですか?

もしそうなら、繰り返しますが、それでも効率的ではありませんが、それでも管理が簡単です、書くことです

SELECT * FROM table 
  WHERE FIND_IN_SET('novel', tags) > 0

ソリューション、正規表現ソリューション、およびソリューションの間で共有されているのは、どちらも列FIND_IN_SETのインデックスを利用できないということです。tagsすべてのクエリは、列に対して何らかの関数を使用しており、インデックスの使用を無効にします。

パフォーマンスが必要で、データ形式が私が思うとおりである場合は、テーブルを正規化することをお勧めします。次のような新しいテーブルを作成しますknown_tag

CREATE TABLE known_tag (
  known_tag_id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(127) CHARSET ascii
);

(独自のデータ型を選択してください)

そして、次のような多対多の接続テーブル。

CREATE TABLE original_table_to_known_tag (
  original_table_id INT UNSIGNED,
  known_tag_id INT UNSIGNED,
  PRIMARY KEY(original_table_id, known_tag_id),
  KEY(known_tag_id)
);

そして最後に、次のようにクエリを実行します。

SELECT 
  table.*
FROM 
  known_tag 
  JOIN original_table_to_known_tag USING (known_tag_id)
  JOIN original_table USING (original_table_id)
WHERE
  known_tag.name = 'novel'
;

このタイプのクエリは適切なインデックスを使用し、大きなテーブルでより効率的になります。

于 2012-07-13T05:15:24.947 に答える
0

12.5.2の使用をご覧ください。正規表現

于 2012-07-13T04:58:01.353 に答える