MySQL从设计上让连接和断开连接都很轻量级,在返回一个小的查询结果方面很高效。
所以运行多个小查询现在已经不是大问题了。
## 6.3.1 一个复杂查询还是多个简单查询
MySQL从设计上让连接和断开连接都很轻量级,在返回一个小的查询结果方面很高效
所以运行多个小查询现在已经不是大问题了。
MySQL内部每秒能够扫描内存中上百万行数据,相比之下,MySQL响应数据给客户端就慢得多了
## 6.3.2 切分查询
将一个大的DELETE语句切分成多个较小的查询可以尽可能小地影响MySQL性能,同时还可以减少MySQL复制的延迟。例如,我们需要每个月运行一次下面的查询:
![](https://box.kancloud.cn/b3ad278f434016026e9d6eef87f888b1_664x340.png)
一次删除一万行数据一般来说是一个比较高效而且对服务器影响也最小的做法(如果是事务型引擎,很多时候小事务能够更高效)。同时,需要注意的是,如果每次删除数据后,都暂停一会儿再做下一次删除,这样也可以将服务器上原本一次性的压力分散到一个很长的时间段中,就可以大大降低对服务器的影响,还可以大大减少删除时锁的持有时间
## 6.3.3 分解关联查询
对关联查询进行分解。可以对每一个表进行一次单表查询,然后将结果在应用程序中进行关联。
![](https://box.kancloud.cn/9e315471db40324b81ded544463d1923_648x293.png)
* 让缓存的效率更高。许多应用程序可以方便地缓存单表查询对应的结果对象。例如,上面查询中的tag已经被缓存了,那么应用就可以跳过第一个查询。再例如,应用中已经缓存了ID为123、567、9098的内容,那么第三个查询的IN()中就可以少几个ID。
对MySQL的查询缓存来说,如果关联中的某个表发生了变化,那么就无法使用查询缓存了,而拆分后,如果某个表很少改变,那么基于该表的查询就可以重复利用查询缓存结果了。
* 将查询分解后,执行单个查询可以减少锁的竞争。
* 在应用层做关联,可以更容易对数据库进行拆分,更容易做到高性能和可扩展。
* 查询本身效率也可能会有所提升。这个例子中,使用IN()代替关联查询,可以让MySQL按照ID顺序进行查询,这可能比随机的关联要更高效。
* 可以减少冗余记录的查询。在应用层做关联查询,意味着对于某条记录应用只需要查询一次,而在数据库中做关联查询,则可能需要重复地访问一部分数据。从这点看,这样的重构还可能会减少网络和内存的消耗。
* 更进一步,这样做相当于在应用中实现了哈希关联,而不是使用MySQL的嵌套循环关联。某些场景哈希关联的效率要高很多。
通过重构查询将关联放到应用程序中将会更加高效,这样的场景有很多,比如:当应用能够方便地缓存单个查询的结果的时候、当可以将数据分布到不同的MySQL服务器上的时候、当能够使用IN()的方式代替关联查询的时候、当查询中使用同一个数据表的时候。