日期:2014-05-16  浏览次数:20682 次

关于mysql优化一些总结

最近在做mysql数据库的一些优化,主要是sql语句的优化。查阅了一些资料加上一些实战,这里简单做一下总结,水平有限,欢迎大家指正:

?

sql优化,一般有两方面:

?

优化io:

?

IO应该是数据库(尤其是数据量比较大的时候)时间开销最大的地方了,所以,IO优化非常重要,我们常用的方法是通过合理的使用索引来减少IO。

?

减少cpu运算:

?

除了IO,减少cpu运算也是一个优化sql的有效手段。order by,,group by,distinct,count …等都是比较消耗cpu的操作,但是,有时候为了更方便的得到想要的查询结果,这些操作还是必须有的。怎么办呢,其实,有时候我们可以将一些操作在程序里 实现,比如,我们有时候将两个表的中间结果放在map或者set中,通过简单的循环进行完成匹配,或者去重等操作。

?

我们的工作环境用的是 innodB,其实,我们用到的优化方式主要就是 先查看sql的执行计划,找出性能瓶颈,然后更合理的使用索引、选择更合适的语句过滤条件、用更轻快的查询替换容易导致查询中间结果臃肿的查询。

?

通过 explain+sql? 我们可以了解sql 的执行计划,通过sql的执行计划,可以了解查询的性能瓶颈,简单对 explain 结果进行说明一下:

?

执行计划包含的信息有:

?

?

1、id:

?

?????????? 表示查询中执行select子句或操作表的顺序

?

??????????

?

??????????? 如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行。

?

??????????? id如果相同,可以认为是一组,从上往下顺序执行;在所有组中,id值越大,优先级越高,越先执行。

?

?

?

2、select_type:

?

? ? ?? 表示查询中每个select子句的类型,可以理解为语句的复杂程度。

?

? ? ? ?? ?????

?

??????????????? SIMPLE:比较简单,查询中不含子查询或UNION

?

???????????????? PRIMARY:若查询中包含子查询或UNION等,最外层查询为PRIMARY

?

???????????????? SUBQUERY:在SELECT 或者 WHERE 后面跟的子查询,该子查询为SUBQUERY

?

???????????????? DERIVED:在FROM后面的子查询为 DIRIVED

?

???????????????? UNION:出现在UNION之后的SELECT,被标记为UNION

?

???????????????? UNION RESULT:从UNION表获取结果的SELECT会被标记为UNION RESULT

?

? ? ? ? ? ? ? ?? 还有一种相关子查询:

?

? ? ? ? ? ? ? ?? DEPENDENT SUBQUERY:是指引用了外部查询列的子查询,即子查询会对外部查询的每行进行一次计算。 ??????????????

?

3、type:

?

? ? ? ? ? ? ? ?? 查询mysql表的方式,又称“访问类型”:

?

? ? ? ? ? ? ? ??

?

?????????????????? 一般来说,从左向右,性能有差到好,但是,有时候强制使用不恰当的索引(ref)性能反而不如全表扫描(ALL)

?

4、possible_keys:

?

??????????????????? mysql可能使用的索引。

?

5、key:

?

??????????????????? 在查询中实际用的索引。

?

6、key_len:

?

??????????????????? 表示实际使用的索引的字节数,可通过该列计算查询中使用的索引长度,该值是通过索引定义计算得来。

?

7、ref:

?

??????????????????? 表示查询中表的连接匹配条件,即哪些列或常量被用于查找索引列上的值。

?

????????????????????

?

????????????????????? 上面例子中:t1的col1匹配t2表的col1,col2匹配了一个常量(const)‘ac’,

?

8、rows:

?

????????????????????? 表示mysql根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数。这一项很重要,它基本能看出sql语句所要查询的行数,直观的显示了sql语句和使用索引的好坏。

?

9、Extra:

?

????????????????????? 包含不适合在其他列中显示但是很重要的额外信息。

?

?????????????????????? a、Using index

?

????????????????????????????? 表示相应的select操作中使用了覆盖索引。

?

????????????????????????????? 覆盖索引:表示包含所有满足查询需要的数据的索引。可以利用索引返回select要选的列表中的字段,而不必根据索引再次读取数据文件。

?

????????????????????????????????????????????????? 如果要使用覆盖索引,一定要注意select列表中只需取出需要的列,不可select * ,因为将所有字段一起做索引会导致索引文件过大,查询性能?????

?

????????????????????????????????????????????????? 下降。

?

????????????????????? b、Using where:

?

??????????????????????????? 表示mysql服务器在存储引擎收到记录后进行 “后过滤”,如果查询没有使用索引,Using where的作用只是提醒我们mysql将用where子句来过滤结果集。

?

????????????????????? c、Using temporary:

?

??????????????????????????? 表示mysql需要使用临时表来存储结果集,常见于order by和group by操作。

?

????????????????????? d、Using filesort:

?

???????????????????????????? mysql中无法利用索引完成的排序操作称为“文件排序”。

?

???????????????????????????? 它不是使用排序的临时表太大导致内存放不下,从而放到硬盘上的“文件排序”,它只是排序(不用索引)。

?

另外,还可以使用 慢查询 和 profile 来查看sql语句的 磁盘IO和内存IO。现在我也不太了解,以后学习到了再为大家说明。

?

下面,我们说一下sql语句的执行顺序:

?

???????????????????? mysql 的sql 语句 执行顺序:

?????????????????? (8)SELECT (9) DISTINCT<select_list>
?????????????