查询优化主要包括两部分:
一mysql查询机制
二mysql不同语句的优化方式
mysql的查询机制
1为什么会出现查询性能低下的情况
主要有,查询不需要的记录,多表连接返回全部列,总是用*取出全部列,重复查询相同的数据等造成。
2衡量查询的开销
主要从,响应时间,扫描的行数,返回的行数可以大概估计查询的开销。这三个指标会记录到慢查询日志中,所以检查慢查询日志也是找出效率低的查询的一种办法(留坑)。同时explain的使用也可以进行判断扫描的行数
一般情况下。语句里面的where条件在mysql中 是经过以下三种处理的,当然不一定都经过,但是效率是从快到慢:
1)在索引中就使用where条件将不需要的数据完全过滤了,这是在存储引擎的层面进行的,也是最好的一种
2)使用了覆盖索引来返回记录,直接从索引中过滤不需要的数据并返回命中的结果,这是在mysql服务层完成的,无需回表查询记录。
3)在数据表中返回记录,然后通过where过滤掉不需要的数据(extra出现where),这是在mysql服务层完成,mysql需要先从数据表读取记录然后过滤。
3查询执行的基础
1)客户端发送一条查询给服务器
2)服务器先检查查询缓存(坑),如果命中缓存则立刻从缓存中将数据返回,否则进入一下一阶段
3)服务器端进行sql解析,预处理,再由优化器生成对应的执行计划
4)mysql根据执行计划调用对应的存储引擎api来执行查询
5)将查询的数据返回客户端
!客户端接受服务器返回的数据是一边查询一边返回的。
!php,mysql_query 会将查询的数据都缓存到内存,然后之后的mysql库函数才从缓存读取数据,这样做的缺点是当数据大的时候,会花好多时间和内存来处理数据。使用mysql_unbuffered-query则php不会有缓存结果。
查询状态(坑)
查询优化处理
in等同于多个or但是快于or
4mysql如何执行关联查询
mysql执行多表连接的顺序是,先从左表(右连接也会被优化器改成左连接)开始找出行,然后每条行去匹配右表,有点感觉左表的数据类似于where条件一样,指导匹配不到数据之后再回到左表找其他的行去匹配右表。
5在同一个表上查询和更新
mysql不允许在同一个表上同时进行查询和更新,不然会报错。
比如:
UPDATE t1 as a set t1.id=(SELECT name from t1 as b where a.id=b.id)
可以用连接更新
UPDATE t1 as a INNER JOIN(SELECT id,name from t1) as b on a.id=b.id set a.name=b.id
mysql不同语句的优化方式
1max(),min()的优化
对于主键id,可以用use index(primary) 和limit1优化
2子查询优化
一句话,尽量使用关联查询替代
3orderby优化
结合之前索引优化,可知,orderby的列必须保持一致顺序,还有必须被索引字段列包含,才能优化。
4groupby优化
松散扫描和紧凑型扫描(坑)
5count优化
count(colum)的时候,可以统计列值的个数,null不会计算在里面
count(*)的时候计算结果集里面的行数
count(*) count(1)count(primary)速度都差不多。
如果在count的时候,发现条件需要查询的行数过多可以用总的数量减去相反条件的行数。
比如
select count(*)from test2 where id<3000000需要扫描行数很多。时间花费比较大 可以改成
select (select count(*) from test2 )- count(*) from test2 where id >=3000000 时间会大幅度减少
6优化多表连接
1)类型一致建索引,同时索引建第二个表的字段就行了
2)orderby groupby只涉及到一个表的字段,这样才能使用索引排序
7优化limit
1)limit a,b 使a尽量小
2)在a比较大的时候会扫描很多无关的行,所以可以找到a对应的主键,定位到主键在limit可以少扫描很多行。
3)使用延迟关联先找出主键,然后用表内连接这个结果,得出数据