如果在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太慢了。任何替代方案?
答案 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