8个SQL错误:您是否犯了这些错误?


8个SQL错误:您是否犯了这些错误?

文章插图
 
SQL编程既令人兴奋又具有挑战性 。即使是经验丰富的SQL程序员,开发人员和数据库管理员(DBA)有时也要面对SQL语言的挑战 。本文旨在帮助用户识别此类严重错误并学习克服它们 。
【8个SQL错误:您是否犯了这些错误?】让我们深入研究以下几节中最严重的8个SQL错误 。
1)LIMIT语句分页查询是最常见的情况之一,但也是一个非常普遍的问题 。例如,对于以下简单语句,DBA通常为type,name和create_time字段添加复合索引 。这种条件排序可有效使用索引并快速提高性能 。这是90%以上的DBA解决此问题的常用方法 。但是,当LIMIT子句更改为" LIMIT 1000000,10"时,程序员经常抱怨仅检索10条记录会花费太长时间 。发生这种情况是因为数据库不知道第1,000,000条记录从何处开始 。因此,即使索引可用,也必须从头开始计算 。通常由于程序员的懒惰而导致出现此性能问题 。在前端数据浏览和分页或大数据的批量导出之类的方案中,可以将上一页的最大值用作查询条件 。重写SQL代码,如下所示:
8个SQL错误:您是否犯了这些错误?

文章插图
 
使用新设计,查询时间基本上是固定的,并且不会随着数据量的增加而改变 。
2)隐式转换当查询变量与SQL语句中的字段定义类型不匹配时,会发生另一种常见错误 。以下语句就是这样的一个例子:
8个SQL错误:您是否犯了这些错误?

文章插图
 
bpn字段定义为varchar(20),MySQL策略是在比较之前将字符串转换为数字 。当函数作用于表字段时,索引变为无效 。前面的问题可能是由应用程序框架自动完成的参数引起的,而不是由于程序员的有意识的错误 。当前,许多应用程序框架都很复杂 。尽管它们使用起来非常方便,但是您还必须意识到它们可能引起的潜在问题 。
3)更新和删除加入尽管实例化功能是MySQL 5.6中引入的,但是请注意,目前仅针对查询语句进行了优化 。手动将UPDATE或DELETE语句重写为JOIN语句 。
例如,在下面的UPDATE语句中,MySQL实际上运行循环或嵌套子查询(DEPENDENT SUBQUERY),并且执行时间相对较长 。
8个SQL错误:您是否犯了这些错误?

文章插图
 
考虑以下执行计划 。
8个SQL错误:您是否犯了这些错误?

文章插图
 
将语句重写为JOIN语句后,子查询选择模式将从DEPENDENT SUBQUERY更改为DERIVED,从而将所需时间从7秒减少到2毫秒 。
8个SQL错误:您是否犯了这些错误?

文章插图
 
请参考以下简化的执行计划 。
8个SQL错误:您是否犯了这些错误?

文章插图
 
4)混合排序MySQL不能将索引用于混合排序 。但是,在某些情况下,用户仍然可以使用特殊方法来提高性能 。
8个SQL错误:您是否犯了这些错误?

文章插图
 
执行计划以全表扫描形式呈现 。
由于is_reply在按照方法重写后仅具有状态0和1,因此执行时间从1.58秒减少到2毫秒 。
8个SQL错误:您是否犯了这些错误?

文章插图
 
5)EXISTS 陈述MySQL仍然使用嵌套子查询来处理EXISTS子句 。例如,考虑下面的SQL语句:
8个SQL错误:您是否犯了这些错误?

文章插图
 
请参考以下执行计划 。
8个SQL错误:您是否犯了这些错误?

文章插图
 
将EXISTS语句更改为JOIN语句可避免嵌套子查询,并将执行时间从1.93秒减少到1毫秒 。
8个SQL错误:您是否犯了这些错误?

文章插图
 
考虑下面的新执行计划 。
8个SQL错误:您是否犯了这些错误?

文章插图
 
6)有条件下推在以下情况下,无法将外部查询条件下推到复杂视图或子查询:
· 汇总子查询
· LIMIT个子查询
· UNION或UNION ALL子查询
· 输出字段中的子查询
在以下语句的执行计划中,请注意,条件在聚集子查询之后起作用 。
8个SQL错误:您是否犯了这些错误?

文章插图
 

8个SQL错误:您是否犯了这些错误?


推荐阅读