MySQL学习笔记——查询性能优化

查询性能优化

  • 查询性能优化主要从查询优化、索引优化、库表结构优化三个方面出发

慢查询基础:优化数据访问

查询性能低下最根本的原因就是访问的数据太多,大部分性能低下的查询都可以通过减少访问的数据量进行优化。

一般有效的分析步骤如下:

  • 确认应用程序是否在检索大量超过需要的数据。这通常意味着访问了太多的行,也有可能是访问了太多的列。
  • 确认MySQL服务器层是否在分析大量超过需要的数据行。

    1. 是否向数据库请求了不需要的数据

    有些查询会请求超过实际需要的数据,然后这些多余的数据会被应用程序舍弃掉。这会给MySQL服务器带来额外的负担,并增加网络开销,另外也会消耗应用服务器的CPU和内存资源

    1. 是否扫描了额外的数据

    如果发现查询需要扫描大量的数据但只返回少数的行,那么通常可以尝试以下技巧来优化:

    • 使用索引覆盖扫描,把所有需要用到的列都放到索引中。
    • 改变库表结构。
    • 重写这个复杂的查询。

重构查询

优化有问题的查询时,目标应该是找到一个更优的方法获取实际需要的数据,而不是一定总是从MySQL获取一模一样的结果集。

  • 复杂查询与简单查询:设计查询的时候需要考虑,是否将一个复杂查询分成多个简单查询。
  • 切分查询:将大查询切分成小查询,每次只返回一小部分查询结果
  • 分解关联查询:简单说就是,可以对每一个表进行一次 单表查询,然后将结果在应用程序中进行关联。

优点: - 缓存效率更高。许多应用程序可以方便地缓存单表查询对应的结果。 - 将查询分解后,执行单个查询可以减少锁的竞争。 - 查询本身的效率也可能有所提升。 - 在应用层做关联,可以更容易的对数据进行拆分,更容易做到高性能和可扩展。 - 可以减少冗余记录的查询。

查询执行的过程

  • 从客户端向服务器请求数据,如果查询语句在缓存中命中(这个过程是通过大小写敏感的哈希值查找来实现)则直接从缓冲中取出结果;否则进入下一阶段
  • 服务器端进行SQL解析、预处理、再由优化器生成对应的执行计划
  • 根据优化器生成的执行计划,调用存储引擎的API来执行查询
  • 将结果返回给客户端

总结一些常用的sql优化方法

再整理

查询优化器

优化策略分为两种:一是静态优化,二是动态优化。静态优化是直接对解析树进行分析,并完成优化。静态优化不依赖于特别的数值。静态优化在第一次完成后就一直有效,是一种“编译时优化”。动态优化则和查询的上下文有关,是一种“运行时优化”。MySQL对查询的静态优化只需要做一次,但对查询的动态优化则在每次执行时都需要重新评估。

MySQL能处理的查询类型:

  • 重新定义关联表的顺序
  • 将外链接转化为内连接
  • 使用等价变换规则
  • 优化COUNT()、MIN()和MAX()
  • 预估并转化为常数表达式
  • 覆盖索引扫描
  • 子查询优化
  • 提前终止查询
  • 等值传播
  • 列表IN()的比较:MySQL会对IN列表进行排序,再使用二分查找,查找速度更快。

排序优化

排序是一个成本很高的操作,所以从性能上考虑,应尽可能避免排序或者尽可能避免对大量数据进行排序。MySQL可以通过索引进行排序,当不能使用索引生成排序结果时,则需要MySQL自己排序。

MySQL两种排序算法:

  • 两次传输排序(旧版本)

    读取行指针和需要排序的字段,对其进行排序,然后再根据排序结果读取所需要的数据行。两次数据传输的成本非常高。

  • 单次传输排序(新版本)

    先读取查询所需要的所有列,然后再根据给定列进行排序,最后直接返回排序结果。

MySQL对count()查询的优化

COUNT()有两种不同的作用:统计某个列值的数量(COUNT(col)),或者可以统计结果集的行数(COUNT(*))。在统计列值时要求列值是非空的(即不统计值为NULL的行)。在执行COUNT()的时候,通配符并不会扩展成所有列,实际上,它会忽略所有的列而直接统计行数。

MyISAM的COUNT()函数执行的非常快,但这是有前提的,即如果没有任何WHERE条件,MyISAM的COUNT()才会非常快。因为此时无须实际的去遍历表来获得行数,MySQL可以利用MyISAM存储引擎的特性来直接获得这个值(MyISAM会存储表的行数)。如果MySQL知道某列col非空,则MySQL内部会将COUNT(col)优化为COUNT(*)。

当统计带有WHERE子句的行数时,MyISAM的COUNT()和其它存储引擎没有任何区别,都需要遍历整张表。


猜你喜欢

转载自blog.csdn.net/caisongcheng_good/article/details/80698821