1

我有以下查询:

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

基本上它会搜索所有匹配的词,除非在搜索词之前或之后有空格。

因此,如果我搜索"novel",这些术语"graphic novel""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 回答