一、先理解一下 MySQL 查问的执行过程
MySQL 在查问时,它是由很多子工作组成的,每个子工作都会耗费肯定的工夫,如果要想优化查问,实际上要优化其子工作,能够打消一些子工作、缩小子工作的执行次数、让子工作执行的更快。
MySQL 查问的执行过程:从客户端到服务器、而后在服务器进行解析、生成执行打算、执行、返回后果给客户端。
执行是最重要的阶段,包含调用存储引擎检索数据、调用后的数据处理、排序、分组等;
查问须要在不同的中央破费工夫,包含网络、CPU 计算、生成统计信息、生成执行打算、锁期待等,尤其是向底层存储引擎检索数据的调用操作,这些调用须要在内存操作、CPU 操作和内存不足时导致的 IO 操作上破费工夫。依据存储引擎不同,可能还会产生大量的上下文切换以及零碎调用。
不必要的额定操作、不必要的反复操作、某些操作执行的太慢都是查问慢的起因,优化查问的目标就是缩小和打消这些操作所破费的工夫。
二、是否查问了不须要的数据
有些查问会查问很多不须要的数据,查问之后,程序中并未应用,这样岂但会给 MySQL 服务器带来额定的累赘,还会减少网络开销,也会耗费应用服务器的 CPU 和内存资源,简而言之,吃多少拿多少。
千万不要有 “把数据都查出来,用 Java 代码过滤”
的想法。
禁止应用select *
进行查问。
三、掂量查问开销的几个重要指标
1、响应工夫
响应工夫能够分为服务工夫和排序工夫。
- 服务工夫指数据库解决这个查问真正破费的工夫;
- 排队工夫指服务器因为期待某些资源而没有真正执行查问的工夫,比方期待 IO 操作、期待行锁。
2、扫描的行数和返回的行数
较短的行的访问速度更快,内存中的行比磁盘中的行的访问速度要快得多。
现实状况下扫描的行数和返回的行数是雷同的。但这种状况并不多见,比方关联查问的时候,服务器必须扫描更多的行能力失去后果,因而,越多的表关联,性能越低。
3、扫描的行数和拜访类型
MySQL 能够通过多种形式查问并返回后果集,速度从慢到快,扫描的行数由多到少,顺次为全表扫描、索引扫描、范畴扫描、惟一索引扫描、常数援用。
最罕用的优化形式是为查问减少一个适合的索引,索引能够让 MySQL 以最高效、扫描行数起码的形式找到须要的记录。
4、个别能够通过 explain 的 Extra 列查看查问的优劣
个别 MySQL 可能应用以下三种形式利用 where 条件,从好到坏顺次为:
- 在索引中应用 where 条件过滤不匹配的记录,这是在存储引擎层实现的;
- 应用索引笼罩扫描,也就是 Extra 中呈现
Using index
,间接从索引中过滤不须要的记录并返回命中的后果,这是在 MySQL 服务器层实现的,无须再回表查问记录; - Extra 中呈现
Using where
,这是在 MySQL 服务器层实现的,MySQL 须要先从数据表读取记录,而后过滤。
Extra 中呈现 Using where
时,能够通过如下形式优化:
- 应用索引笼罩扫描,把所有须要的列都放到索引中,这样就不必回表查问了;
- 扭转表构造,比方应用汇总表;
- 重写 sql,让 MySQL 优化器可能以更优化的形式执行这个 sql;