我有一个为MySQL编写的查询,它应该在多个表中搜索特定的数据片段,然后拉出一个“ReferenceID”来引用一个包含原始文档详细信息的主表。我可以快速搜索这些项目,但是当我尝试从主表中提取特定内容时,它似乎只是捶打磁盘而不是仅仅检索数据。
我想要做的查询看起来像这样:
SELECT ReferenceID as refid, Title as title, Contents as content, TimeSecs as age
FROM tabledata u
WHERE u.ReferenceID IN (SELECT DISTINCT a.ReferenceID as refid FROM table1 a WHERE a.Table1Item = "[item]"
UNION SELECT DISTINCT b.ReferenceID as refid FROM table2 b WHERE b.Table2Item = "[item]"
UNION SELECT DISTINCT c.ReferenceID as refid FROM table3 c WHERE c.Table3Item = "[item]")
ORDER BY TimeSecs DESC LIMIT 50
ReferenceID搜索中的SELECT查询也可能包含多个OR语句,但无论如何,这样的查询可能需要20-30秒,即使三个表中的查询搜索可能需要半秒钟。 / p>
此外,更令人困惑的是它使用filesort来浏览“tabledata”表,即使对于其他每个查询都没有。还为其适当的列和表创建了索引。
我输出了一个解释来证明这一点:
+----+------------------+--------------+----+----------------------+-----------+-------+-----+------+----------------------------+
|id |select_type |table |type|possible_keys |key |key_len|ref |rows |Extra |
+----+------------------+--------------+----+----------------------+-----------+-------+-----+------+----------------------------+
|1 |PRIMARY |u |ALL |NULL |NULL |NULL |NULL |659659|Using where; Using filesort |
|2 |DEPENDENT SUBQUERY|a |ref |ReferenceID,Table1Item|ReferenceID|98 |func |3 |Using where; Using temporary|
|3 |DEPENDENT UNION |b |ref |ReferenceID,Table2Item|Table2Item |386 |const|14 |Using where; Using temporary|
|4 |DEPENDENT UNION |c |ref |ReferenceID |ReferenceID|98 |func |11 |Using where; Using temporary|
|5 |DEPENDENT UNION |d |ref |ReferenceID |ReferenceID|98 |func |7 |Using where; Using temporary|
|NULL|UNION RESULT |<union2,3,4,5>|ALL |NULL |NULL |NULL |NULL |NULL | |
+----+------------------+--------------+----+----------------------+-----------+-------+-----+------+----------------------------+
总的来说,我确实得到了我想要的结果,但没有得到及时的结果。
答案 0 :(得分:0)
您对查询的表达方式,SQL引擎可能会生成整个参考ID列表,然后开始查看它们。
请改为尝试:
SELECT ReferenceID as refid, Title as title, Contents as content, TimeSecs as age
FROM tabledata u
WHERE exists (SELECT 1
FROM table1 a
WHERE a.Table1Item = "[item]" and u.ReferenceID = a.ReferenceID
) or
exists (SELECT 1
FROM table2 b
WHERE b.Table2Item = "[item]" and u.ReferenceID = b.ReferenceID
) or
exists (SELECT 1
FROM table3 c
WHERE c.Table3Item = "[item]" and u.ReferenceID = c.ReferenceID
)
ORDER BY TimeSecs DESC
LIMIT 50;
然后确保在三个表中的每个表上都有ReferenceID, TablexItem
的索引。