Closed. This question needs to be more
focused。它当前不接受答案。
想改善这个问题吗?更新问题,使其仅通过
editing this post专注于一个问题。
4年前关闭。
在一项作业中,给了我一个查询,并要求对其进行优化。
查询是:
选择
C.yearID作为年份,
名称为teamName,
C.lgID作为联盟,
D.cnt作为totalBatters,
C.cnt如上
从
(选择
count(masterID)as cnt,A.yearID,A.teamID,A.lgID
从
(选择
masterID,
teamID,
yearID,
lgID,
总和(AB)
总和(H)
sum(H)/ sum(AB)平均
从
棉絮
GROUP BY teamID,yearID,lgID,masterID)B,(选择
teamID,
yearID,
lgID,
总和(AB)
总和(H)
sum(H)/ sum(AB)平均
从
棉絮
其中ab不为null
GROUP BY teamID,yearID,lgID)A
哪里
A.avg> = B.avg AND A.teamID = B.teamID
AND A.yearID = B.yearID
AND A.lgID = B.lgID
GROUP BY teamID,yearID,lgID)C,
(选择
count(masterID)as cnt,yearID,teamID,lgID
从
棉絮
其中ab不为null
GROUP BY yearID,teamID,lgID)D,
团队
哪里
C.cnt / D.cnt> = 0.75
AND C.yearID = D.yearID
AND C.teamID = D.teamID
AND C.lgID = D.lgID
AND team.yearID = C.yearID
AND team.lgID = C.lgID
AND team.teamID = C.teamID
我想知道如何做才能优化此效果?我是这个概念的新手,对如何进行操作有些困惑。通常,如何优化其中具有select语句的子查询?
通常,如何优化其中具有select语句的子查询?
这里有一些想法可以帮助您入门。我将尊重一个事实,那就是它是一个任务,最后,您自己动手并逐步学习,将对SQL查询有更好的了解。
我希望该赋值包括可以导入MySQL的某种数据集,以便您可以在进行更改时运行查询并注意到对执行计划和整体性能的影响。
别名
甚至在考虑优化之前,也许您都可以研究如何使代码更易于阅读,理解和维护。子查询的行为类似于常规表,因此,应为子查询赋予别名/名称,以使数据集有意义。
它们是别名B
,A
,C
和D
,它们看起来几乎是故意被混淆的,但是实际上您会惊讶地发现,在现实的生产SQL代码中经常看到不良的命名/别名。
尝试单独查看(如果可以运行)每个子查询,查看字段及其含义,然后用好名字替换别名,并相应地更新不同列中的引用。这将优化查询,以提高清晰度,并最终实现可维护性。
JOIN
s
希望在完成这项工作时,已经涵盖了各种JOIN
操作。如果不是,请输入here is a good summary from a StackOverflow answer。还有很多其他资源涵盖了JOIN
的内容,包括关于TechOnTheNet的不错的帖子。
让我们精简子查询,并查看整个查询的结构。我将逻辑替换为注释,以使其更加明显:
SELECT
--columns
FROM
(
SELECT
--columns
FROM
(
select
--columns
FROM batting
) B,
(
select
--columns
) A
WHERE
--some comparisons of averages
) C,
(
SELECT
--columns
FROM batting
) D,
teams
WHERE
--a filter based on a calculation
C.cnt / D.cnt >= 0.75
--um... what is all this stuff doing down here?
--shouldn't those be in a JOIN?
AND C.yearID = D.yearID
AND C.teamID = D.teamID
AND C.lgID = D.lgID
AND teams.yearID = C.yearID
AND teams.lgID = C.lgID
AND teams.teamID = C.teamID
您是否注意到任何奇特的东西或看起来很奇怪的东西?如果您以前没有阅读过此内容,强烈建议您阅读
Bad habits to kick : using old-style JOINs的
Aaron Bertrand。
阅读后,再次查看此查询的框架,使用现代
JOIN
可以进行的改进应该很突出。这将使查询在清晰度和可维护性方面更加优化。
关键字大小写一致性
使关键字更具可读性的另一种方法是使用一致的大写字母。实际上,使用
CAPITAL CASE
和
small case
大约为50/50。对于一个脚本来说,这似乎无关紧要,但是当这种不一致之处散布在整个代码库中时,对于下一个不得不在其中进行开发和维护的人来说,这可能会很烦人。
性能
因此,到现在为止,如果您已经应用了所有内容,则应该更容易解密代码。就性能而言,有两点对我不利。有很多聚合,因此有很多
GROUP BY
。
首先查看每个子查询本身,然后查看每个聚合。查看如何在整个查询的上下文中使用每个字段。看看您可能能够删除哪些对象,也许是写查询的人最初认为他们会需要,但最终却没有使用并忘记删除它们。
对
GROUP BY
字段尝试相同的策略,这些字段是具有一个或多个聚合操作的查询中所包含的每个未聚合的字段。
GROUP BY
可能会变得非常昂贵,并且派生子查询也具有
GROUP BY
的事实使情况更加复杂。
您还可以尝试其他一些技巧,这些技巧更高级,可以在I / O受损的情况下提高执行效率,例如,将一个或多个子查询的结果集提取到临时表中,这将释放主表上的锁。
诸如此类的优化不一定总能提高执行速度,但是在数据库服务器处于负载状态的生产环境中,速度通常不是优化的主要考虑因素,而是“轻便”(或者占用很小的负载空间)。服务器)通常比原始速度有价值得多,而原始速度最终会占用更多资源。
我希望这有帮助!