在连接表时,需要更快的FIND_IN_SET替代方案

时间:2011-09-09 11:56:37

标签: mysql sql join

如果在TABLE2逗号分隔列中找到TABLE1 ID,我想执行select。

table1:
+---------+
| id      |
+---------+
|12345678 |
+---------+
|12322222 |
+---------+

table2:
+---------------------------------------------+
| manyids                                     |
+---------------------------------------------+
|12345678,1111111,2222233,0000111,65321       |
+---------------------------------------------+
|2222233,12322222                             |
+---------------------------------------------+
|12322222                                     |
+---------------------------------------------+

这在较小的测试表上正常工作:

SELECT table1.id,
COUNT(table1.id) AS occurences
FROM table1 JOIN table2 ON FIND_IN_SET(table1.id, table2.manyids ) > 0
GROUP BY table1.id HAVING occurences > 0 
ORDER BY occurences DESC

然而实际的TABLE1我想执行select有超过500k行而FIND_IN_SET太慢了。任何替代方案?

1 个答案:

答案 0 :(得分:6)

唯一明智的替代方案是规范化表格:

实施例

table tag
---------
id integer auto_increment primary key
name varchar(40)

table article
-------------
id integer auto_increment primary key
title varchar(1000)
content text

table tag_link
--------------
article_id integer foreign key references article(id)
tag_id integer foreign key references tag(id)
primary key article_id, tag_id

由于所有字段都已编入索引,因此您可以轻松快速地进行查询:

SELECT t.name FROM article AS a
INNER JOIN tag_link tl ON (tl.article_id = a.id)
INNER JOIN tag t ON (t.id = tl.tag_id)
WHERE a.id = '45785'

选项2糟糕的想法,比选项1更糟糕
如果您确实无法更改设置,请在字段fulltext上创建manyids索引。

并将查询更改为:

SELECT table1.id,
COUNT(table1.id) AS occurences
FROM table1 
JOIN table2 ON MATCH(table2.manyids) 
               AGAINST (CONCAT("+'",table1.id,"'") IN BOOLEAN MODE)  
/*boolean mode is required*/
GROUP BY table1.id HAVING occurences > 0 
ORDER BY occurences DESC

如果任何ID在禁用词列表中,则不匹配。请注意,此列表中没有数字。

<强>链接
http://dev.mysql.com/doc/refman/5.5/en/fulltext-stopwords.html
http://dev.mysql.com/doc/refman/5.5/en/fulltext-boolean.html

请注意,您需要调整全文索引考虑的最小和最大字长:请参阅:http://dev.mysql.com/doc/refman/5.5/en/fulltext-fine-tuning.html