MySQL查询优化-内部查询
这是整个查询MySQL查询优化-内部查询,mysql,sql,optimization,Mysql,Sql,Optimization,这是整个查询 SELECT s.*, (SELECT url FROM show_medias WHERE show_id = s.id AND is_primary = 1) AS media_url FROM (shows As s) WHERE `s`.`id` IN ( SELECT DISTINCT st.show_id FROM show_time_schedules AS sts LEFT JOIN show_times AS st ON st.id = sts.show_t
SELECT s.*, (SELECT url FROM show_medias WHERE show_id = s.id AND is_primary = 1) AS media_url
FROM (shows As s)
WHERE `s`.`id` IN (
SELECT DISTINCT st.show_id
FROM show_time_schedules AS sts
LEFT JOIN show_times AS st ON st.id = sts.show_time_id
WHERE sts.schedule_date BETWEEN CAST('2012-01-10' AS date) AND CAST('2012-01-14' AS date)
)
AND `s`.`is_active` = 1
ORDER BY s.name asc
如果
而且
SELECT DISTINCT st.show_id
FROM show_time_schedules AS sts
LEFT JOIN show_times AS st ON st.id = sts.show_time_id
WHERE sts.schedule_date BETWEEN CAST('2012-01-10' AS date) AND CAST('2012-01-14' AS date)
(0.0061 sec)
有没有明显的原因
SELECT s.*, (inner query 1) AS media_url
FROM (shows As s)
WHERE `s`.`id` IN ( inner query 2 )
AND `s`.`is_active` = 1
ORDER BY s.name asc
是否需要5.7245秒
解释扩展的
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY s ALL NULL NULL NULL NULL 151 100.00 Using where; Using filesort
3 DEPENDENT SUBQUERY sts ALL NULL NULL NULL NULL 26290 100.00 Using where; Using temporary
3 DEPENDENT SUBQUERY st eq_ref PRIMARY PRIMARY 4 bvcdb.sts.show_time_id 1 100.00 Using where
2 DEPENDENT SUBQUERY show_medias ALL NULL NULL NULL NULL 159 100.00 Using where
您可以随时使用来查看MySql对查询的处理情况
您也可以用稍微不同的方式编写查询,您是否尝试过以下方法
SELECT s.*,
sm.url AS media_url
FROM shows AS s
INNER JOIN show_medias AS sm ON s.id = SM.show_id
WHERE `s`.`id` IN (
SELECT DISTINCT st.show_id
FROM show_time_schedules AS sts
LEFT JOIN show_times AS st ON st.id = sts.show_time_id
WHERE sts.schedule_date BETWEEN CAST('2012-01-10' AS date) AND CAST('2012-01-14' AS date)
)
AND `s`.`is_active` = 1
AND sm.is_primary = 1
ORDER BY s.name asc
看看这会有什么样的影响是很有趣的。我希望它会更快,因为目前,我认为MySql将为您的每一个节目运行内部查询1(这样一个查询将运行多次。连接应该更有效)
如果您想要所有在show_Media中没有行的节目,请将内部联接替换为左联接
编辑:
我很快就会看一看你的解释,我也不知道你是否想试试下面的解释;它将删除所有子查询:
SELECT DISTINCT s.*,
sm.url AS media_url
FROM shows AS s
INNER JOIN show_medias AS sm ON s.id = SM.show_id
INNER JOIN show_times AS st ON (s.id = st.show_id)
RIGHT JOIN show_time_schedules AS sts ON (st.id = sts.show_time_id)
WHERE `s`.`is_active` = 1
AND sm.is_primary = 1
AND sts.schedule_date BETWEEN CAST('2012-01-10' AS date) AND CAST('2012-01-14' AS date)
ORDER BY s.name asc
(如果能看到对这些问题的解释得到扩展也会很好——您可以将其添加到这篇评论中)
进一步编辑:
关于你的解释()
使用文件端口和使用临时文件都是关键指标。我建议的第二个查询应该删除所有临时表(在子查询中)。然后试着把订单撇在一边,看看这是否会有不同(我们可以在目前的调查结果中加上这一点:-)
我还可以看到,查询可能会错过很多索引查找;您的所有id列都是索引匹配的主要候选列(与通常的相同)。我还会尝试添加这些索引,然后再次运行EXPLAIN EXTENDED,看看现在有什么不同(编辑,我们已经从上面的评论中知道了!)下面是CTE解决方案:(我的错,mysql没有CTE,但问题太普遍了) 结果:
CREATE TABLE
INSERT 0 15
id | study_start_time | study_end_time
------+------------------+----------------
1234 | 168 | 480
2345 | 175 | 233
2345 | 400 | 425
4567 | 200 | 225
4567 | 250 | 289
4567 | 300 | 310
4567 | 320 | 340
4567 | 360 | 390
(8 rows)
查询计划(添加明显主键和索引后):
出于兴趣,您是否通过(内部,左侧,取决于您是否只想要带有url的节目)在show_medias.show_id=s.id上加入show_medias而不是在选择列表中执行子查询来查看性能?我很想看看。“解释查询”中有什么内容吗?@dash非常感谢您迄今为止的帮助,添加了
EXPLAIN EXTENDED
,您建议的查询产生了几乎相同的(如果不是更长的6.x秒)性能。您知道表上有哪些索引吗?特别是,您的查询索引中是否有任何id列用于显示、显示时间、显示时间和显示媒体?出于兴趣,是否通过加快查询速度来删除顺序?@dash我的天哪。。。谢谢你提到索引。。。这是一个旧的项目,我在学习索引外部id字段和主。。。应用外键索引后,查询将以0.0064秒的速度运行。。。把这些加在你的答案上,我们会把这件事结束的。。。谢谢MySQL支持这个吗?如果真是这样,那就太棒了!然而,我想你可能看错了问题;-)不,没有,对不起。我没有看到mysql标签,或者它是后来添加的。CTE是追踪链表的好方法(这就是我重新标记孤岛和缺口的原因;IAG基本上是链表,所以CTE对我来说就像膝盖反射)我将添加一个查询计划,只是为了好玩…因此我的回答;-)然而,我很想知道这个问题属于哪一个,因为这是一个出色的、结构良好的、得到充分支持的答案。。。
WITH RECURSIVE tree AS (
SELECT t0.id
, t0.study_start_time
, t0.study_end_time
FROM tab t0
WHERE NOT EXISTS (SELECT * FROM tab nx
WHERE nx.id=t0.id
AND nx.study_end_time = t0.study_start_time
)
UNION
SELECT tt.id
,tt.study_start_time
,t1.study_end_time
FROM tab t1
JOIN tree tt ON t1.id=tt.id
AND t1.study_start_time = tt.study_end_time
)
SELECT * FROM tree
WHERE NOT EXISTS (SELECT * FROM tab nx
WHERE nx.id=tree.id
AND tree.study_end_time = nx.study_start_time
)
ORDER BY id
;
CREATE TABLE
INSERT 0 15
id | study_start_time | study_end_time
------+------------------+----------------
1234 | 168 | 480
2345 | 175 | 233
2345 | 400 | 425
4567 | 200 | 225
4567 | 250 | 289
4567 | 300 | 310
4567 | 320 | 340
4567 | 360 | 390
(8 rows)
DROP TABLE
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "tab_pkey" for table "tab"
CREATE TABLE
CREATE INDEX
INSERT 0 15
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------
Merge Anti Join (cost=16209.59..16292.13 rows=6386 width=12) (actual time=0.189..0.193 rows=8 loops=1)
Merge Cond: ((tree.id = nx.id) AND (tree.study_end_time = nx.study_start_time))
CTE tree
-> Recursive Union (cost=0.00..15348.09 rows=8515 width=12) (actual time=0.022..0.136 rows=15 loops=1)
-> Merge Anti Join (cost=0.00..175.04 rows=1455 width=12) (actual time=0.019..0.041 rows=8 loops=1)
Merge Cond: ((t0.id = nx.id) AND (t0.study_start_time = nx.study_end_time))
-> Index Scan using tab_pkey on tab t0 (cost=0.00..77.35 rows=1940 width=12) (actual time=0.010..0.018 rows=15 loops=1)
-> Index Scan using sssss on tab nx (cost=0.00..77.35 rows=1940 width=8) (actual time=0.003..0.008 rows=14 loops=1)
-> Merge Join (cost=1297.04..1500.28 rows=706 width=12) (actual time=0.010..0.012 rows=1 loops=6)
Merge Cond: ((t1.id = tt.id) AND (t1.study_start_time = tt.study_end_time))
-> Index Scan using tab_pkey on tab t1 (cost=0.00..77.35 rows=1940 width=12) (actual time=0.001..0.004 rows=9 loops=6)
-> Sort (cost=1297.04..1333.42 rows=14550 width=12) (actual time=0.006..0.006 rows=2 loops=6)
Sort Key: tt.id, tt.study_end_time
Sort Method: quicksort Memory: 25kB
-> WorkTable Scan on tree tt (cost=0.00..291.00 rows=14550 width=12) (actual time=0.000..0.001 rows=2 loops=6)
-> Sort (cost=726.15..747.44 rows=8515 width=12) (actual time=0.166..0.169 rows=15 loops=1)
Sort Key: tree.id, tree.study_end_time
Sort Method: quicksort Memory: 25kB
-> CTE Scan on tree (cost=0.00..170.30 rows=8515 width=12) (actual time=0.025..0.149 rows=15 loops=1)
-> Sort (cost=135.34..140.19 rows=1940 width=8) (actual time=0.018..0.018 rows=15 loops=1)
Sort Key: nx.id, nx.study_start_time
Sort Method: quicksort Memory: 25kB
-> Seq Scan on tab nx (cost=0.00..29.40 rows=1940 width=8) (actual time=0.003..0.004 rows=15 loops=1)
Total runtime: 0.454 ms
(24 rows)