本章内容实际上是非常重要的,但是我认为这本书写的并不好,也许是翻译问题,也许是印刷问题,有些地方模糊不清,有些地方前后矛盾,所以遇到这种地方只得跳过或者简单阐述。
一、查询优化注意事项
思考一个查询为何如此慢的时候主要有如下几条:
- 可能在查询不需要的记录,比如查询大量的数据到应用服务器,然后在代码里只拿取前几条,抛弃剩余的几万条数据
- 多表关联查询语句,返回全部的列而不是需要的列
- SELECT ,据说SELECT后面跟着的都应该好好审视是否真的需要全部拿出数据。(现在大量地使用ORM框架,情况就不一样了,你不可能只让ORM框架拿一个实体的一部分内容,一般查询都是一整个对象拿出来。不过大多数ORM框架都在应用层做了一次缓存,拿一次之后,效率就很高了,事实上这又是另一个问题了,缓存可是要耗费内存的,内存不够用也是白搭)
- 重复查询相同的数据而不知道缓存高频数据。(我觉得这个也要看情况的吧,现在网络很快了,如果我们忽略网络消耗,这种被反复查询的数据,或者说反复运行的SQL都是被Mysql缓存起来的,既然Mysql已经帮我们在数据库的出口处做了缓存,我们何必再在服务器的入口处再做一次缓存呢,当然,还是要根据实际情况来决定)
- 检查Mysql是否在扫描额外的记录,扫描的行数是否远大于返回的行数,如果是这样,那说明这个查询可能写的糟透了。扫描的行数一般在返回的行数的1倍到10倍之间是正常的。(可以用explain语句来查看Mysql预估会扫描多少行)
- 检查索引以及覆盖索引是否被使用,如果有机会使用,为什么没被使用
二、一个复杂的查询还是多个简单的查询
答案是后者。 还是那句话,现在网络以及非常快了,网络不再是很大的瓶颈,如果一个复杂的查询能被拆分成多个简单的查询,肯定是要拆分的好。 但是也别太过了,如果能在一条查询里完成,并且性能并不差,那就没有理由拆开。
三、分批查询
有时候一个大的查询可以分批地执行,比如删除数据。
四、分解关联查询
这个和第二条理由差不多,只不过是更具体的一种情况。(所以你可以知道这章写的有多乱) 书中列出了这样做的好处:
- 让缓存效率更高,多表关联的话,只要有一个表变化,缓存就不能用了,拆分成几个表的查询,然后在应用服务器这边整合,就可以保证缓存效率更高。
- 查询分解后,减少锁竞争,因为同一时间锁住的表更少
- 在应用层做关联,扩展性好,容易拆分数据库
- Mysql的关联是嵌套关联,一层一层地关联,效率低下,扫描到的数据更多。后文有讲
五、整个查询流程简介