
文章插图
数为90万,时间消耗为12秒 。

文章插图
由于最后 WHERE 条件以及排序均针对最左主表,因此可以先对 my_order 排序提前缩小数据量再做左连接 。SQL 重写后如下,执行时间缩小为1毫秒左右 。

文章插图
再检查执行计划:子查询物化后(select_type=DERIVED)参与 JOIN 。虽然估算行扫描仍然为90万,但是利用了索引以及 LIMIT 子句后,实际执行时间变得很小 。

文章插图
08、中间结果集下推再来看下面这个已经初步优化过的例子(左连接中的主表优先作用查询条件):

文章插图
那么该语句还存在其它问题吗?不难看出子查询 c 是全表聚合查询,在表数量特别大的情况下会导致整个语句的性能下降 。
其实对于子查询 c,左连接最后结果集只关心能和主表 resourceid 能匹配的数据 。因此我们可以重写语句如下,执行时间从原来的2秒下降到2毫秒 。

文章插图
但是子查询 a 在我们的SQL语句中出现了多次 。这种写法不仅存在额外的开销,还使得整个语句显的繁杂 。使用 WITH 语句再次重写:

文章插图
总结
数据库编译器产生执行计划,决定着SQL的实际执行方式 。但是编译器只是尽力服务,所有数据库的编译器都不是尽善尽美的 。
上述提到的多数场景,在其它数据库中也存在性能问题 。了解数据库编译器的特性,才能避规其短处,写出高性能的SQL语句 。
程序员在设计数据模型以及编写SQL语句时,要把算法的思想或意识带进来 。
编写复杂SQL语句要养成使用 WITH 语句的习惯 。简洁且思路清晰的SQL语句也能减小数据库的负担。
推荐阅读
- 用 C# 实现一个简单的日志框架
- 普洱中老茶价格表,普洱茶价格表
- 谈谈Nginx负载均衡中的6种均衡策略
- 烂大街的Nginx+Redis分布式锁+MQ+MDB架构设计
- 未婚先孕的姑娘有多惨 古代未婚先孕会怎么样
- 带有天地的成语有哪些成语 有天地的成语有哪些
- 秦子婴下一个位皇帝是谁 秦子婴是秦始皇的儿子吗
- 安卓面试题到处攒,一到面试就忘个干净?来看看这份超详细的整理
- 得陇望蜀这个成语讲的是谁 得陇望蜀是谁的典故
- 面试必问的 Redis:RDB、AOF、混合持久化
