企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
**优化** 查询优化、索引优化、库表结构优化 # 6.2 慢查询基础:优化数据访问 1.确认应用程序是否在检索大量超过需要的数据。这通常意味着访问了太多的行,但有时候也可能是访问了太多的列。 2.确认MySQL服务器层是否分析大量超过需要的数据行 **查询不需要的记录** 例如在新闻网站中取出100条记录,但是只是在页面上显示前面10条)。他们认为MySQL会执行查询,并只返回他们需要的10条数据,然后停止查询。实际情况是MySQL会查询出全部的结果集,客户端的应用程序会接收全部的结果集数据,然后抛弃其中大部分数据。最简单有效的解决方法就是在这样的查询后面加上LIMIT。 **多表关联时返回全部列** 查询所有在电影Academy Dinosaur中出现的演员 比如: ![](https://box.kancloud.cn/90ea914764d78dcf6dad3e21307d61f8_620x120.png) 应该: ![](https://box.kancloud.cn/b401d83329adc1bfa68633f11fd73aa0_648x49.png) 如果应用程序使用了某种缓存机制,获取并缓存所有的列的查询,相比多个独立的只获取部分列的查询可能就更有好处。 **重复查询相同的数据** 比较好的方案是,当初次查询的时候将这个数据缓存起来,需要的时候从缓存中取出,这样性能显然会更好 ## 6.2.2 MySQL是否在扫描额外的记录 衡量查询开销: ![](https://box.kancloud.cn/6c2dc3a592b8121e02c8bd6ab92f5d39_141x122.png) 这三个指标都会记录到MySQL的慢日志中,所以检查慢日志记录是找出扫描行数过多的查询的好办法。 **响应时间:** 见书 **扫描的行数和返回的行数** 理想情况下扫描的行数和返回的行数应该是相同的。但实际情况中这种“美事”并不多。例如在做一个关联查询时,服务器必须要扫描多行才能生成结果集中的一行。扫描的行数对返回的行数的比率通常很小 在EXPLAIN语句中的type列反应了访问类型,扫描表、扫描索引、范围访问和单值访问,速度从慢到快。 一般MySQL能够使用如下三种方式应用WHERE条件,从好到坏依次为: •在索引中使用WHERE条件来过滤不匹配的记录。这是在存储引擎层完成的。 •使用索引覆盖扫描(在Extra列中出现了Using index)来返回记录,直接从索引中过滤不需要的记录并返回命中的结果。这是在MySQL服务器层完成的,但无须再回表查询记录。 •从数据表中返回数据,然后过滤不满足条件的记录(在Extra列中出现Using Where)。这在MySQL服务器层完成,MySQL需要先从数据表读出记录然后过滤。 ***** type列 MySQL找到数据行的方式,即访问类型。效率从最差到最好的顺序如下: ALL 全表扫描,没有用到任何的索引,这是一种非常原始的查找方法,非常的耗时二号抵消。 index 这种类型只是另一种形式的全部扫描,只不过它的扫描顺序是按照索引的顺序,然后根据索引回表取数据。和All相比,他们都是取得了全表的数据,而且index要先读索引再回表取数据。 如果连接类型为type,而且extra列中的值为‘Using index’,那么称这种情况为索引覆盖。 rang rang指的是有范围的索引扫描,相交于index的全索引扫描,它有范围限制,因此要优于index。 它是基于索引的,表示WHERE条件中对索引列使用了BETWEEN AND、>、 <、 IN、OR。 ref 查找条件使用索引而且不为主键或unique。表示虽然使用了索引,但该索引列的值不唯一,有重复。这样即使使用索引找到了第一条数据,仍然需要进行目标值附近的小范围扫描,但它的好处是不用全表扫描。 -ref_eq 进行精确查询,结果集唯一,表示使用了主键或唯一性索引查找的情况。 const,system 当MySQL能对查询部分进行优化,并且转换为一个常量。比如,where条件使用主键查询。 extra列 这一列包含的是不在其他列显示的额外信息。 using index 这个说明MySQL使用覆盖索引,避免了回表操作,效率不错。 using where 服务器在存储引擎收到行后会进行过滤。即会根据查询条件过滤结果集。 这表示服务器在存储引擎返回行以后再应用WHERE过滤条件。 using file sort 表示排序的时候没有用到索引,不得不采取其他方式排序。排序方法有内存排序,在临时文件排,采用双路排序法,或者是采用整行排序等,using file sort并没有说是那些排序方法。 using temporay 表示用到了一张临时表,至于临时表是在内存中还是在磁盘上就不知道了。 *****