SQL语句的执行顺序:
1.限制语句
打击查询是最常用的场景之一,但通常是最容易出现问题的场景。可以有效地用于索引,并且性能得到迅速提高。
好吧,就是这样解决了超过90%的DBA。但是,当限制子句变成“限制1000000,10”时,程序员仍然抱怨:为什么我只拍摄10个记录?
您必须知道数据库不知道100,000条记录从哪里开始,即使有索引,您也需要对其进行计算一次。在大多数情况下,程序员很懒惰。
在前端数据浏览页面的场景中,或批处理大数据的导出,上一页的最大值可以用作参数作为查询条件。SQL重新设计如下:
在新设计下,查询时间基本上是固定的,并且随着数据量的增加不会改变。
2. cissed转换
在SQL语句中,查询变量和字段定义类型不匹配是另一个常见错误。例如,以下句子:
字段BPN定义为VARCHAR(20)。MySQL的策略是在比较数字之前将字符串转换为数字。在表字段,索引故障上的构造行为。
上面的情况可能是应用程序框架自动填充的参数,而不是程序员的原始意图。现在,应用程序框架非常复杂。使用和小心很方便。它可以自己挖掘。
3.相关更新,删除
尽管MySQL5.6介绍了实现特征,但有必要特别注意查询语句的优化。手工重写以更新或删除是必要的。
例如,以下更新语句,MySQL实际上执行了可以想象的圆形/嵌套子问题。
实施计划:
重写为加入之后,子查询的选择模式已从依赖的子查询变为派生,这已经大大加速了执行速度,从7秒到2毫秒。
执行计划被简化为:
4.混合分类
MySQL不能将索引用于混合分类。但是在某些场景中,仍然有机会使用特殊方法来提高性能。
执行计划显示为完整表扫描:
由于IS_Reply只有两个状态:0和1,因此我们根据以下方法重写,并且执行时间从1.58秒减少到2毫秒。
5.存在陈述
当MySQL Treats存在条款时,它仍然使用嵌入式查询的执行方法。如下所示,下面的SQL语句:
执行计划是:
删除存在以避免嵌套的查询,从而将执行时间从1.93秒减少到1毫秒。
新执行计划:
6.在条件下推
外部查询条件不能将其推向复杂的视图或sub -queries ::
1.多锁定查询;2.包含极限的子查询;3.工会或工会所有查询;4.输出字段中的子查询;
例如,可以从执行计划中可以看到以下语句,即条件在集聚查询上作用:
通过语义确定查询条件后,您可以将其直接推开,并按照以下方式重写:
执行计划变为:
7.提前减少范围**
首先转到初始SQL语句:
SQL语句的原始含义是:首先建立一系列左连接,然后排序以获取前15个记录。从执行计划中也可以看到,最后一步是估算900,000的排序记录的数量,时间消耗为12秒。
因为最后一个条件和排序针对左派,因此可以在MY_ORDER排序之前提前减少数据量。SQL重写如下,并且执行时间减少到约1毫秒。
再次检查执行计划:在查询之后参加(select_type =派生)以参与JOIN。尽管估计的扫描仍为900,000,但使用索引和限制子句后,实际执行时间很小。
8.推出中间结果
让我们看一下下面的初步优化的示例(左图中主观察中的优先查询条件):
因此,此语句中还有其他问题吗?不难看到子查询C是一个完整的表聚合查询,当表格的数量特别大时,这会导致整个语句的性能。
实际上,对于子Query C,左连接的最终结果集仅关心可以匹配Main Watch ResourceID的数据。因此,我们可以按以下方式重写语句,并且执行时间从原始2下降秒至2毫秒。
但是,该子Query A在我们的SQL语句中出现了很多次。本文不仅存在额外的开销,而且使整个声明变得复杂。请使用语句再次重新写下:
总结
数据库编译器生成了执行计划,以确定SQL的实际执行。但是,编译器只是尝试使用,并且所有数据库的编译器都不是完美的。
上面提到的大多数方案在其他数据库中也存在性能问题。理解数据库编译器的特征,我们可以避免缺点并写出高性能的SQL语句。
在设计数据模型和编写SQL语句时,请引入算法的思维或意识。
编写复杂的SQL语句以培养使用使用语句的习惯。简单而清晰的SQL语句也可以减轻数据库的负担。
以上是该共享的所有内容。如果您想了解更多信息,请转到公共帐户:Python编程学习圈,每日干货共享
原始:https://juejin.cn/post/7097429759528796197