【发布时间】:2013-08-08 14:39:51
【问题描述】:
我有这个问题
SELECT
shot.hole AS hole,
shot.id AS id,
(SELECT s.id FROM shot AS s
WHERE s.hole = shot.hole AND s.shot_number > shot.shot_number AND shot.round_id = s.round_id
ORDER BY s.shot_number ASC LIMIT 1) AS next_shot_id,
shot.distance AS distance_remaining,
shot.type AS hit_type,
shot.area AS onto
FROM shot
JOIN course ON shot.course_id = course.id
JOIN round ON shot.round_id = round.id
WHERE round.uID = 78
这会在大约 0.7 秒内返回 900~ 行。这没问题,但需要更多这样的行
(SELECT s.id FROM shot AS s
WHERE s.hole = shot.hole AND s.shot_number > shot.shot_number AND shot.round_id = s.round_id
ORDER BY s.shot_number ASC LIMIT 1) AS next_shot_id,
例如
(SELECT s.id FROM shot AS s
WHERE s.hole = shot.hole AND s.shot_number < shot.shot_number AND shot.round_id = s.round_id
ORDER BY s.shot_number ASC LIMIT 1) AS past_shot_id,
添加这会将加载时间增加到 10 秒,这太长了,页面通常根本无法加载,或者 MySQL 只是锁定,使用 show processlist 表明查询只是坐在那里 sending data。
删除这些子查询中的ORDER BY s.shot_number ASC 子句将查询时间减少到0.05 秒,这要好得多。但是需要ORDER BY 来确保返回下一个或过去的行(镜头),而不是任何旧的随机行。
如何改进此查询以使其运行更快并返回相同的结果。也许my approach 用于获取下一行和过去的行是次优的,我需要寻找一种不同的方式来返回下一行和上一行的 ID?
编辑 - 附加背景信息
查询在我的测试域(子域)上很好。但是当移动到实时域时,问题就开始了。几乎没有任何改变,但由于这些新的缓慢查询,整个站点都停止了。重点说明:
- 不同的域
- /var/www 中的不同文件夹
- 相同的数据库
- 相同的数据库凭据
- 相同的代码
- 添加索引以尝试修复 - 这没有帮助
这些是否会影响加载时间?
【问题讨论】:
-
你能弄清楚如何将相关子查询重写为不相关子查询吗?或者完全省略子查询>
-
@JakeNoble 。 . .镜头是增量分配的吗?有差距吗?
-
这应该是可能的@Strawberry - 应该提高速度吗?
-
@GordonLinoff 有差距,出手可能是 1,2,4,6,8
-
:-) @jakenoble 如果我不认为它会,我不会建议它。也就是说,我之前错了……
标签: mysql subquery query-optimization