1、LIMIT 语句

分页查询是最常用的场景之一,但也通常也是最容易出问题的地方。比如对于下面简单的语句,一般 DBA 想到的办法是在 type, name, create_time 字段上加组合索引。这样条件排序都能有效的利用到索引,性能迅速提升。

好吧,可能90%以上的 DBA 解决该问题就到此为止。但当 LIMIT 子句变成 “LIMIT 1000000,10” 时,程序员仍然会抱怨:我只取10条记录为什么还是慢?要知道数据库也并不知道第1000000条记录从什么地方开始,即使有索引也需要从头计算一次。出现这种性能问题,多数情形下是程序员偷懒了。

在前端数据浏览翻页,或者大数据分批导出等场景下,是可以将上一页的最大值当成参数作为查询条件的。SQL 重新设计如下:

在新设计下查询时间基本固定,不会随着数据量的增长而发生变化。

2、隐式转换

SQL语句中查询变量和字段定义类型不匹配是另一个常见的错误。比如下面的语句:其中字段 bpn 的定义为 varchar(20),MySQL 的策略是将字符串转换为数字之后再比较。函数作用于表字段,索引失效。上述情况可能是应用程序框架自动填入的参数,而不是程序员的原意。现在应用框架很多很繁杂,使用方便的同时也小心它可能给自己挖坑。

3、关联更新、删除

虽然 MySQL5.6 引入了物化特性,但需要特别注意它目前仅仅针对查询语句的优化。对于更新或删除需要手工重写成 JOIN。

比如下面 UPDATE 语句,MySQL 实际执行的是循环/嵌套子查询(DEPENDENT SUBQUERY),其执行时间可想而知。执行计划:重写为 JOIN 之后,子查询的选择模式从 DEPENDENT SUBQUERY 变成 DERIVED,执行速度大大加快,从7秒降低到2毫秒

执行计划简化为:

4、混合排序

MySQL 不能利用索引进行混合排序。但在某些场景,还是有机会使用特殊方法提升性能的。

执行计划显示为全表扫描:

由于 is_reply 只有0和1两种状态,我们按照下面的方法重写后,执行时间从1.58秒降低到2毫秒。

5、EXISTS语句

MySQL 对待 EXISTS 子句时,仍然采用嵌套子查询的执行方式。如下面的 SQL 语句:

执行计划为:

去掉 exists 更改为 join,能够避免嵌套子查询,将执行时间从1.93秒降低为1毫秒。

新的执行计划:6、条件下推外部查询条件不能够下推到复杂的视图或子查询的情况有:

  • 聚合子查询;
  • 含有 LIMIT 的子查询;
  • UNION 或 UNION ALL 子查询;
  • 输出字段中的子查询;

如下面的语句,从执行计划可以看出其条件作用于聚合子查询之后确定从语义上查询条件可以直接下推后,重写如下:

执行计划变为:

7、提前缩小范围先上初始 SQL 语句:

数为90万,时间消耗为12秒。

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

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

8、中间结果集下推

再来看下面这个已经初步优化过的例子(左连接中的主表优先作用查询条件):

那么该语句还存在其它问题吗?不难看出子查询 c 是全表聚合查询,在表数量特别大的情况下会导致整个语句的性能下降。

其实对于子查询 c,左连接最后结果集只关心能和主表 resourceid 能匹配的数据。因此我们可以重写语句如下,执行时间从原来的2秒下降到2毫秒。

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

总结数据库编译器产生执行计划,决定着SQL的实际执行方式。

但是编译器只是尽力服务,所有数据库的编译器都不是尽善尽美的。上述提到的多数场景,在其它数据库中也存在性能问题。

了解数据库编译器的特性,才能避规其短处,写出高性能的SQL语句。程序员在设计数据模型以及编写SQL语句时,要把算法的思想或意识带进来。

编写复杂SQL语句要养成使用 WITH 语句的习惯。简洁且思路清晰的SQL语句也能减小数据库的负担 。

sql select distinct常见错误_这8种常见的SQL错误用法,80%的程序员还在犯相关推荐

  1. SQL基础---SQL SELECT DISTINCT 语句

    SQL SELECT DISTINCT 语句 本章讲解 SELECT DISTINCT 语句. SQL SELECT DISTINCT 语句 在表中,可能会包含重复值.这并不成问题,不过,有时您也许希 ...

  2. SQL SELECT DISTINCT 语句 用法

    SQL SELECT DISTINCT 语句 在表中,可能会包含重复值.这并不成问题,不过,有时您也许希望仅仅列出不同(distinct)的值. 关键词 DISTINCT 用于返回唯一不同的值. 语法 ...

  3. 第5章 SQL SELECT DISTINCT 语句教程

    SELECT DISTINCT 语句用于return 唯一不同的值. 第5章 SQL SELECT DISTINCT 语句教程 在表中,一个列可能会包含多个重复值,有时也许希望仅仅列出不同(disti ...

  4. PHP程序员最易犯10种错误_莫枫恋_新浪博客

    PHP是个伟大的web开发语言,灵活的语言,但是看到php程序员周而复始的犯的一些错误.我做了下面这个列表,列出了PHP程序员经常犯的10中错误,大多数和安全相关.看看你犯了几种. 1.不转意html ...

  5. PHP 程序员最易犯10种错误

    PHP程序员经常犯的10中错误,大多数和安全相关.看看你犯了几种 1.不转意html entities 一个基本的常识:所有不可信任的输入(特别是用户从form中提交的数据) ,输出之前都要转意. e ...

  6. PHP程序员最易犯10种错误

    PHP是个伟大的web开发语言,灵活的语言,但是看到php程序员周而复始的犯的一些错误.我做了下面这个列表,列出了PHP程序员经常犯的10中错误,大多数和安全相关.看看你犯了几种. 1.不转意html ...

  7. 一般编译器错误_Java程序员最容易犯的10个错误

    人非圣贤,孰能无过.都说Java语言是一门简单的编程语言,基于C++演化而来,剔除了很多C++中的复杂特性,但这并不能保证Java程序员不会犯错. 在开发 Java 软件时可能会遇到许多类型的错误,但 ...

  8. Java程序员最常犯的 10 个错误

    转载自 Java程序员最常犯的 10 个错误 这个列表总结了Java开发人员经常犯的10个错误. 一 .把数组转成ArrayList 为了将数组转换为ArrayList,开发者经常会这样做: List ...

  9. java list top_Java程序员最常犯的错误盘点之Top 10

    原标题:Java程序员最常犯的错误盘点之Top 10 人非圣贤,孰能无过.都说Java语言是一门简单的编程语言,基于C++演化而来,剔除了很多C++中的复杂特性,但这并不能保证Java程序员不会犯错. ...

最新文章

  1. C++:多线程中的小白(2)线程启动、结束、创建线程、join、detach
  2. 用matlab绘制一个时钟
  3. mysql外键依靠主键_mysql设置外键(主键依赖)
  4. 64位树莓派运行linux,树莓派3B+安装64位debian GUN/Linux系统
  5. UVA116 单向 DSP(多段图最短路)
  6. 2018年度中国LC3盛大召开!
  7. 《三国演义》里到底描写了多少个人物,你知道吗?
  8. SCS【1】今天开启单细胞之旅,述说单细胞测序的前世今生
  9. 硬盘突然变raw格式_移动硬盘分区变为RAW格式的终极解决办法
  10. 因为一个MySQL权限问题引发的填坑之一(ERROR1045:Access Denied for user 'root'@'localhost' (using password:YES))
  11. 牛!程序媛一口气拿下BAT、美团、vivo、爱奇艺等公司Offer面经总结
  12. 【图像原理】rgb数字图片概念之显示器成像原理
  13. “简单证明GUID(全局唯一标识符)并不唯一”
  14. 在Spring MVC框架下利用RESTful API和MongoDB实现用户留言与邮件反馈
  15. npm 和 cnpm 区别
  16. 简要介绍Eclipse
  17. [从头读历史] 第287节 神之物语 赫拉克勒斯的故事
  18. miflash 刷机超过1000s还未完成
  19. C语言--gets、puts、scanf、printf函数详细用法与区别(小白也能看懂,看不懂私信骂我)
  20. 画质增强概述-2-应用场景

热门文章

  1. 深入理解SpringCloud之Eureka注册过程分析
  2. kill 的常用信号
  3. 跟我一起学extjs5(22--模块Form的自己定义的设计)
  4. 玻森新闻自动摘要算法介绍
  5. Cocos2d-X中国象棋的发展《五岁以下儿童》摆棋
  6. Xcode 4.6.3 Bug - .m 文件不能正常打开,uitableveiwController
  7. 怎么把pdf转成word
  8. cmd jar 无效_为什么我的JAR文件以CMD执行,而不是双击执行?
  9. java文件操作_Java文件操作大全
  10. Python如何连接Mysql及基本操作