大量数据,大部分性能欠佳的查询都可以用减少数据访问的方式进行修改。在分析性能较低的查询的时候,查明应用程序是否正在获取超过需要的数据,即访问了过多的行或列,以及MySQL服务器是否分析了超过需要的行。一些查询先向服务器请求不需要的数据,然后再丢掉它们。这给服务器造成了额外的负担,增加了网络开销,消耗了内存和CPU资源。222重构查询当优化有问题的查询时,并不意味着一定要从MySQL得到完全一样的结果,偶尔可以用完全等价的方式得到更好的性能。如果不同的查询能提供更高的效率,尽管得到的结果不同,也可以考虑重写查询。也许最终应用程序的代码也会和查询一起被改写。
221
fMySQLServerSQL结果查询缓存解析树
解析器
预处理器
结果
查询执行计划
查询优化器
解析树
查询执行引擎API调用存储引擎I
oDBMyISAMetc数据
查询的执行路径
223
复杂查询一个重要的查询设计问题就是是否可以把一个复杂查询分解成多个简单的
查询。大多数时候,都强调用用尽可能少的查询做尽可能多的事情。这种方式的积极意义在于它可以减少查询解析和优化的步骤,并且代码量较少。但是对于数据量较大的查询来说,通过分解查询可以得到更高的效率,同时也使程序更易于维护和扩展。可以使用分治法,让查询在本质上不变,但是每次只执行一小部分,以减少受影响的行数,清理陈旧数据也是一种很好的方式。想得到高性能,最佳的方式就是了解MySQL如何优化和执行查询,一旦理解了背后的机制,那么很多优化工作就简化为纯粹的推理,并且也可以理解查询优化过程中的逻辑性。224分解联接在较复杂实际应用中,可以采用“分解联接”把一个多表联接分解成多个单个查询,然后在应用程序端实现联接操作,尽管从代码初看上去比较浪费,其实
f也只是增加了查询的数量而已,但是这种分解方式有很好的性能优势,查询本身会更高效,能使缓存的效率更高,如果一个表经常改变,那么分解联接就可以减少缓存失效的次数;同时对于MyISAM表来说,每个表一个查询可以更有效地利用表锁,因为查询会锁住单个表较短时间,而不是把多个表长时间锁住,有时在应用程序端进行联接可以更方便扩展数据库。225查询缓存MySQL有一种称为查询缓存的缓存机制,它可以保留查询返回给客户端的完整结果。当缓存命中的时候,服务器马上返回保存的结果,并跳过解析、优化和执行步骤。MySQL将查询缓存完全存储在内存中,缓存不仅仅存储了查询结果,它在某种程度上像一个文件系r