MySQL——查询性能优化

一、为什么查询速度会慢

通常来说:查询生命周期大致可以按顺序来看:从客户端,到服务器,然后在服务器上进行解析,生成执行计划、执行,并返回结果给客户端

执行可以认为是整个生命周期中最重要的阶段,包括大量的检索数据到存储引擎的调用以及调用后的数据处理(排序和分组等)。

二、慢查询基础:优化数据访问

查询性能低下最基本的原因是访问的数据太多。

① 确认应用程序是否在搜索大量超过需要的数据。

② 确认MySQL服务器层是否在分析大量超过需要的数据行。

1、是否向数据库请求了不需要的数据

① 查询不需要的记录

-- 若页面上只有需要10行数据  返回100行甚至更多是得不偿失的 最简单方法  limit
select <cols> from table where col_name = 'col_val'  limit 10;

常见的错误认识:MySQL只返回需要的结果集,实际上MySQL是先返回全部结果集再进行运算的,

-- 以前公司分页框架 查询count时
select count(<cols>) from table where ...
-- 这个时候MySQL会查询出全部<cols>然后进行count处理,查询效率很低,可优化为
select count(1) from table where ...

② 总是取出全部的列+多表关联时返回全部的列

查询中应该拒绝使用 '*'

select * from table where ...
-- * 会查询所有的列,平常学习或者解决问题时用*没有问题,但不要在生产应用中使用*
-- 特别是多表关联时  会查询出所有的表的所有列 数据量巨大

③ 避免重复查询相同的数据

热点数据,最好使用缓存解决。避免重复不断地查询相同的数据。

2、MySQL是否扫描了额外的记录

对于MySQL,最简单的衡量查询的指标:响应时间、扫描的行数、返回的行数。

① 响应时间

在日常开发中,需要重视响应时间。一般公司都会周期统计响应时间过长的SQL。响应时间=服务时间+排队时间。

② 扫描的行数与返回的行数

分析查询时:查看该查询扫描的行数是非常有帮助的。这在一定程度上能够说明该查询找到需要的数据的效率高不高。理想情况下扫描的行数=返回的行数,但实际操作过程中多表联合查询出一行数据是常态。

-- 注意explain sql 返回列表中的rows属性:扫描的行数

③ 扫描的行数和访问类型

-- explain sql 返回列表中的type属性:访问类型
-- 速度从慢到快 扫描的行数也是从小到大
-- all :全表扫描
-- index :索引扫描
-- range :范围扫描 一般要求最少要达到range
-- ref :非唯一索引扫描
-- eq_ref:唯一索引扫描
-- cons :常熟引用

④ 一般MySQL能够使用三种方式应用where条件(extra : using where),从好到坏依次是:

a 在索引中使用where条件过滤不匹配的记录。这是在MySQL存储引擎层完成的

b 使用索引覆盖(覆盖索引)扫描来返回记录(extra :using index),直接从索引中过滤不需要的记录并返回命中的结果。这是由MySQL服务器层完成的。

c 从数据表中返回数据,然后过滤不满足条件的记录(extra : using where)。这也是在MySQL服务器层完成的。

select actor_id,count(1) from sakila.film_actor group by actor_id;
-- 误区:应用where条件不是sql中的where
-- 当actor_id是二级索引 对应a
-- 当actor_id是主键索引(聚簇)对应b
-- 当actor_id不是索引    对应c

⑤ 查询需要扫描大量的数据只返回少量的行,通常有下列技巧优化

a 使用索引覆盖扫描,把所有需要返回的列都放到索引中,存储引擎无须回表获取对应的行就可以返回数据了。

b 改变库表结构。使用单独的汇总表

c 重写这个复杂的查询

三、重构查询的方式

参考《高性能MySQL》

猜你喜欢

转载自www.cnblogs.com/wqff-biubiu/p/12359873.html