一 什么样的sql需要进行优化
1 查询次数多且每次查询占用时间长的sql
通常为分析工具pt-query-digest 分析的前几个查询
2 IO大的SQL
注意pt-query-digest分析中的Rows examine项
3 未命中索引的SQl
注意pt-query-digest 分析中Rows examine 和Rows Send的对比
数据库的瓶颈呢 可能更多的是处在IO的层次 (如果直接对IO进行的优化也是对性能起到的优化)
如果一条sql扫描的行数越多 说明 IO消耗越大
如果扫描行数远远大于他的发送行数即 Rows examine 比Rows Send大的多 就索引的应用率就不高
二 通过explain查询和分析SQL的执行计划
极力避免表扫描
在查询中呢 在不损失精确性的情况下 长度越短越好 因为mysql每次读取的数据都是以页为单位的 而一页中存在的索引的数量越大呢 查询的效率越高
extra列返回的值 需要格外注意
三 Max()函数的优化(创建索引) 和count()函数的优化
索引是进行顺序排列的 如果用MAX函数求某一个字段的最大值时 如果该字段没有索引就需要进行表扫描的操作 那么IO就是非常高的 所以此时在该字段上创建一个索引是非常好的优化方案
count的优化 count (*) 和count(字段) 是有区别的
count(字段)不包含空值null
count(*)包含null
四 子查询的优化
通常情况下 需要把子查询优化为join查询 但在优化时要注意关联健是否有一对多的关系 要注意重复数据 如果有一对多关系的话 使用连接查询
1 inner join on
2 left join on
3 right join on
把子查询优化成连接查询时 为了防止出现重复数据 使用distinct函数进行去重
五 group by 分组的优化
使用gropu by和Order by 的时候很容易出现 临时表或者 文件排序的方式而且容易进行表扫描操作 为了避免文件排序 和临时表的产生
通过关联子查询 让查询使用索引 而避免产生临时表或者文件排序 这样就会减少大量的Io 也可以增加一些过滤的条件 总之要避免产生临时文件 减少io操作
六 Limit优化
limit常用于分页处理 时常会伴随oder by从句使用 因此大多数时候会使用Filesorts这样会造成大量的IO问题
常用的优化方式1
innor DB 是按照主键的逻辑顺序进行排序的
所以 使用有索引的列或主键进行Order by操作 就可以避免很多的IO操作
但是如果数据量大了之后 仍有问题
这个时候可以记录上次返回的主键 在下次查询时使用主键过滤
在具体的sql中就是说 先加入where条件把要扫描的行数缩小的一个范围内 然后在进行排序 (前提是主键是进行顺序排序的和连续的)
总之就是尽量避免过多的扫描
七 关于索引的优化 如何选择合适的列建立索引
1 在where从句 group by从句 order by 从句 on 从句中出现的列 建立索引
2 索引字段越小越好 (数据库中存储数据是以页为单位的 字段越小一页所能展示的数据就越多 就能尽可能的减少IO的操作提高效率)
3 判断列的离散值高低取决于该列的唯一值大小 唯一值越多 离散型越好 可选择行越高(如果列不多可以建立联合索引 建立联合索引将离散度大的列放到联合索引的前面)
八 重复及冗余索引
1 . 过多的索引呢 不但会影响写入的效率 同时还会影响查询(因为数据在进行查询分析的时候,会选择运用哪一个索引如果索引越多 那么分析的过程越慢 也会影响查询的效率)
2 所以删除不必要的索引 就显得尤为重要 比如如果建立了主键 那么就没有必要在该列上在建立唯一索引 因为主键就是唯一索引的一种具体形式
3 innodb的特性 会在每一个索引的后面追加主键的信息 如果在人为的追加主键信息的话 那么这个索引就是一个冗余的索引
4 使用pt-duplicate-key-checher工具检查重复及冗余索引