对于低效的查询,我们发现通过以下两个步骤分析很有效:
(1)确认应用程序是否在检索大量超过需要的数据。这通常意味着访问了太多的行,但有时候也可能是访问了太多的行
(2)确认MySQL服务器层是否在分析大量超过需要的数据行
优化查询的方法如下:
(1)是否向数据库请求了不需要的数据
对于查询数据是,可能应用程序会查询了太多不需要的数据,这会造成两方面的缺点
①会给MySQL服务器带来额外的负担,并增加网络开销
②另外也会消耗应用服务器的CPU
这里有一些典型的案例:
①查询不需要的记录:MySQL在查询时,实际上会先返回全部的结果集然后再进行计算,并不是只返回需要的数据。这也就是说如果你先select大量的数据然后再截取前几条记录的话,那么就意味着会浪费性能。因为MySQL实际上是先查询出全部的结果集再抛弃大部分数据给你,并不是返回你要的那几条数据。最简单有效的就是加一个limit进行限制
②多表关联时返回全部列:
对于以上写法应改成
③总是取出所有列:尽量不要使用select *的写法。因为这会导致优化器无法完成索引覆盖这类优化,还会为服务器带来额外的I/O,内存和CPU的消耗。当然查询返回超过需要的数据并不总是坏事,比如当应用程序使用了某种缓存机制,或者有其他考虑,获取超过需要的数据叶可能是有其好处,打不要忘记这样做的代价。获取并缓存所有的列的查询,相比多个独立的只获取部分列的查询可能就更有好处
④重复查询相同的数据:不断的重复执行相同的查询,然后每次都返回完全相同的数据。比如:用户评论是不断抓取用户头像的url,这时候就可以通过缓存机制,从缓存中取出,不需要重复查询。
(2)MySQL是否在扫描额外的记录
对于MySQL最简单的衡量查询开销的三个指标:①响应时间 ②扫描的行数 ③返回的行数。没有那个指标能够完美的衡量查询的开销,但他们可以大致的反应MySQL在内部执行查询时需要访问多少数据,并可以大概推算出查询运行的世界。这三个指标会被记录在MySQL的慢查询中,所以查询慢日志记录是找出扫描行数过多的查询的好办法
①响应时间:响应时间由两个部分组成:服务时间和排队时间。服务时间是指数据库处理这个查询真正花了多长时间。排队时间是指服务器因为等待某些资源(比如锁竞争,等待I/O等)而没有真正执行查询的世界。
然而在不同类型的应用压力下,响应时间并没有一致的规律或者公式。诸如存储引擎的锁、高并发资源竞争、硬件响应等诸多因素都会影响响应时间。所以响应时间既可能是一个问题的结果也可能是一个问题的原因,不同案例情况不同。
所以当你看到一个响应时间的时候,首先要问问自己这个响应时间是不是一个合理的值
②扫描的行数和返回的行数:扫描的行数对于我们分析查询时非常有帮助了,这在一定程度上能够说明该查询找出需要的数据的效率高不高。对于找出那些糟糕的查询,这个指标可能还不够完美,因为并不是所有的行的访问代价都是相同的。较短的行的访问速度更快,内存中的行也比磁盘中的行的访问速度要快得多
理想情况下扫描的行数=返回到行数。但是现实很残酷,一般没有这种操作。
③扫描的行数和访问类型:在评估查询开销的时候,需要考虑一下从表中找到某一行数据的成本。MySQL有好几种访问方式可以查找并返回一行结果。有些访问方式可能需要扫描很多行才能返回一行,也有些访问方式可能无需扫描就能返回结果。
在EXPLAIN语句中的type列反映了访问类型。访问类型有很多种,从权标扫描到索引扫描、范围扫描、唯一索引查询、常数引用等。这里列的这些,速度从慢到快,扫描的行数从小到大。
如果查询没有办法找到合适的访问类型,那么解决的最好办法通常就是增加一个合适的索引(索引让MySQL以最高效、扫描函数最少的方式找到需要的记录)
如果发现查询需要扫描大量的数据但是只返回少数的行,那么通常可以使用下面的技巧进行优化
①使用索引覆盖扫描,把索引需要用的列都放到索引当中,这样存储引擎无需回表获取对应行就可以返回结果 ②该表库表结果。例如使用单独的汇总表 ③重写这个复杂的查询,让MySQL优化器能够以更优化的方式执行这个查询。
原文地址:https://www.cnblogs.com/tijie/p/10673206.html