请问有关子查询的帮助吗?
当我在本地XAMP mySQL数据库上运行查询时,查询需要2秒钟才能完成。然而,在我的网络服务器上使用相同的数据库,相同的查询需要98秒加上返回相同的结果。
当我说相同时,记录会从HeidiSQL导出和插入,所以我确定数据集没问题。数据库DDL也是从HeidiSQL创建的,但我猜我可能错过了创建数据库精确副本的一些关键步骤。
我还使用Heidi的导出功能创建了fiddle。虽然我应该指出查询在小提琴上的执行速度比在现实生活中快得多。
我正在执行的查询是......
SELECT d.dayID, d.dayDate, d.item, w.Idx, w.word, w.wordID, w.asize, w.span
FROM words w
INNER JOIN days d ON w.dayID = d.dayID
WHERE w.word IN (
SELECT w1.word
FROM words w1
INNER JOIN days d1 ON w1.dayID = d1.dayID
WHERE d1.dayDate = '2012-02-27'
AND d1.Item = 'a'
AND w1.span = 24
AND w1.asize = 6
)
AND w.span = 24
AND w.asize = 6
GROUP BY d.dayDate, d.item
Order by d.dayDate, w.asize DESC, w.Idx;
它的目的是从days表中返回Days和Items的列表,其中word表中有重复的单词。
上面的查询将返回与此类似的结果......
dayID dayDate item Idx word wordID asize span
1974 2012-11-22 B 3 item b 1367339 6 24
4370 2015-03-10 B 1 item b 3024989 6 24
使用phpMyAdmin,我在单词字段中添加了一个索引,这使得时间从98秒减少到46秒。但是,当然,46秒也太长了?
其他要注意的一点是,现实中的单词表包含约300万条记录。其他查询(非子查询)在眨眼之间运行。我想我只是在子查询中吮吸。
请问有人可以指出我正确的方向,以确定在服务器上执行查询需要这么长时间的原因吗?
答案 0 :(得分:1)
作为一般规则,在处理复杂或大的子查询时,应避免使用IN
。这是因为IN
条件必须为数据源中的每一行评估一次。因此,如果您的数据源有1000行且IN
条件有1000个元素,那么执行将是这样的:
(不用说,如果子查询很复杂,那将是一个巨大的性能损失)
所以,你可以采取一些措施来加快速度:
IN
JOIN
JOIN
我将处理选项2.如果需要,可以使用完整子查询替换临时表。
所以,让我们创建一个临时表:
drop table if exists temp_words;
create temporary table temp_words
SELECT w1.word
FROM words w1
INNER JOIN days d1 ON w1.dayID = d1.dayID
WHERE d1.dayDate = '2012-02-27'
AND d1.Item = 'a'
AND w1.span = 24
AND w1.asize = 6;
alter table temp_words
add index w(word);
现在,不要使用IN
,而是使用JOIN
:
SELECT d.dayID, d.dayDate, d.item, w.Idx, w.word, w.wordID, w.asize, w.span
FROM words w
INNER JOIN days d
ON w.dayID = d.dayID
INNER JOIN temp_words as w1 -- Replace 'temp_words' with your subquery
-- if you don't want to use a temp table
ON w.word = w1.word
WHERE w.span = 24
AND w.asize = 6
GROUP BY d.dayDate, d.item
Order by d.dayDate, w.asize DESC, w.Idx;
我认为您使用JOIN
代替IN
会发现性能大幅提升。
关于临时表的必须了解的事情: