MySQL 执行一条 select 语句,期间发生了什么?
Laiyong Wang Lv6

参考网址

https://www.xiaolincoding.com/mysql/base/how_select.html

本文记录下基于 SQL 查询流程,可能导致查询速度慢的情况(自己总结,细节部分 chatGPT ,错误欢迎指正)

  1. 网络原因
    连接 mysql 服务使用 tcp ,三次握手避免不了,四次挥手的时间取决于是短链接还是长连接
    由于 MySQL 在执行查询过程中临时使用内存管理连接对象,如果长连接累计很多,将导致 MySQL 服务占用内存太大,可能会导致系统变慢,甚至会被系统强制杀掉,可定期断开长连接或者客户端主动重置连接(使用函数 mysql_reset_connection())

  2. 查询缓存
    字面意思,以sql查询语句为键,sql查询语句的结果为值,若是缓存有则直接返回,无需查表来提升查询速度。
    所以写sql时尽量将长sql拆分成多个短sql,便于命中缓存。
    但是对于更新比较频繁的表,查询缓存的命中率很低,因为只要一个表有更新操作,那么这个表的查询缓存就会被清空。若刚缓存了个查询结果很大的数据且没被使用的时候,刚好这个表有更新操作,查询缓冲就被清空了,相当于缓存了个寂寞
    所以MySQL 8.0 版本直接将查询缓存删掉了,也就是说 MySQL 8.0 开始,执行一条 SQL 查询语句,不会再走到查询缓存这个阶段了。
    所以查询缓存MySQL8.0版本之前可使用,且最好时查询功能较多的系统来进行使用

  3. 索引

    • 未使用索引
      就是未使用索引,导致全表查询
    • 索引失效
      • 隐式转化(常见于使用订单号查询订单,直接一串数字,不会使用索引)
        列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引
        据类型出现隐式转化。如varchar不加单引号的话可能会自动转换为int型,使索引无效,产生全表扫描
        隐式转换name = ‘111’ 会使用到 name = 111 不会使用到
        因为当name值为111a 111q 111sxzcs都会跟111匹配
      • 不符合索引最左前缀原则
        对于复合索引,只有在查询的条件满足索引的最左前缀时,索引才能被充分利用。如果查询条件不符合最左前缀原则,那么索引可能无法有效使用,导致索引失效。
      • 使用函数或表达式
        查询中使用了函数或表达式对索引列进行了处理,那么索引可能无法被有效利用。例如,WHERE DATE_FORMAT(date_column, ‘%Y-%m’) = ‘2023-12’,这种情况下,即使 date_column 上存在索引,也无法被利用
        还有常用的 like 语句,若是时%开头,也会索引失效
      • 数据分布不均匀(这个我认为是创建表时的问题,重复率太高就不该有索引)
        索引列上的数据分布不均匀,例如某些值出现的频率过高或过低,那么索引可能无法提供良好的性能,甚至导致索引失效
      • 数据量过大
        对于某些大型表,索引可能无法完全载入内存,这样在执行查询时会导致频繁的磁盘 I/O 操作,影响查询性能
      • 使用 NOT、OR 等条件(这个我不熟,贴个图片,免得以后再看忘了)
        upload successful
  4. 比较好玩的问答

    • 同一条sql,同一个数据库,早上查询很快,下午很慢,为什么
    • 数据库服务器负载(可回答),网络问题(可回答),查询缓存(可回答),索引失效(可回答,为什么会失效?这点非常好玩,因为从上午到下午,表里面可能插入了大量数据,导致数据分布不均匀还有数据量过大,参考第三点)
$li-margin-bottom = 0.8rem $post-tool-button-width = 2.5rem .post-tools-container { padding-top var(--component-gap) .post-tools-list { li { margin-bottom $li-margin-bottom &:last-child { margin-bottom 0 } } li.tools-item { position relative box-sizing border-box width $post-tool-button-width height $post-tool-button-width color var(--text-color-3) font-size 1.2rem background var(--background-color-1) border-radius 50% box-shadow 2px 2px 5px var(--shadow-color) cursor pointer &:hover { box-shadow 2px 2px 8px var(--shadow-hover-color) } i { color var(--text-color-3) } &:hover { color var(--background-color-1) background var(--primary-color) i { color var(--background-color-1) !important } } &.toggle-show-toc { display none } &.go-to-comments { .post-comments-count { position absolute top 0 right -1rem display none align-items center justify-content center box-sizing border-box min-width 1.1rem height 1.1rem padding 0 0.2rem color var(--badge-color) font-size 12px background var(--badge-background-color) border-radius 0.4rem +keep-tablet() { display none !important } } } } li.status-item { width $post-tool-button-width height $post-tool-button-width color var(--text-color-3) font-size 1.6rem cursor pointer &.post-lock { cursor default .fa-lock-open { display none color var(--keep-success-color) } &.decrypt { cursor pointer .fa-lock-open { display block } .fa-lock { display none } } } } } }