论坛首页 综合技术论坛

数据库之优化二

浏览 3297 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-03-28  
  前面也有一些优化的策略,现在在看看一些优化关于Group BY 语句、 Order By语句 等。

优化GROUP BY语句
   默认情况下,MySQL对所有GROUP BY col1,col2...的字段进行排序。这与在查询中指定ORDER BY col1,col2...类似。因此,如果显式包括一个包含相同的列的ORDER BY子句,则对MySQL的实际执行性能没有什么影响。 如果查询包括GROUP BY 但用户想要避免排序结果的消耗,则可以指定ORDER By NULL禁止排序,例如:
引用

  explain select id, sum(moneys) from sales2 group by id \G
  
  explain select id, sum(moneys) from sales2 group by id order by null \G

你可以通过比较发现第一条语句会比第二句在Extra:里面多了Using filesort.而恰恰filesort是最耗时的。


优化ORDER BY语句
    在某些情况中,MySQL可以使用一个索引来满足ORDER BY子句,而不需要额外的排序。WHERE 条件和 ORDER BY使用相同的索引,并且ORDER BY的顺序和索引顺序相同,并且ORDER BY的字段都是升序或者都是降序。
例如:
引用

SELECT * FROM t1 ORDER BY key_part1,key_part2,....:
SELECT * FROM t1 WHERE key_part1 = 1 ORDER BY key_part1 DESC,key_part2 DESC;
SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 DESC;

但是以下的情况不使用索引:
引用

SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 ASC;
--ORDER by的字段混合ASC 和 DESC

SELECT * FROM t1 WHERE key2=constant ORDER BY key1;
----用于查询行的关键字与ORDER BY 中所使用的不相同

SELECT * FROM t1 ORDER BY key1, key2;
----对不同的关键字使用ORDER BY


优化嵌套查询
   MySQL4.1开始支持SQL的子查询。这个技术可以使用SELECT语句来创建一个单列的查询结果,然后把这个查询结果作为过滤条件用在另一个查询中,使用子查询可以一次性地完成多逻辑上需要多个步骤才能完成的SQL操作,同时也可以避免事务或者表锁死,并且些起来也很容易。但是,有些情况下,子查询可以被更有效的连接(JOIN)替代。
例如:
引用

  explain select * from sales2 where company_id not in(select id from company2) \G

explain select * from sales2 left join comany2 on sales2.company_id = company2.id  where sales2.company_id is null \G;

第一句看起来比第二句更简洁,但是第二句比第一就更快。因为使用JOIN来完成这个查询,速度比较快,尤其如果对compay2表中的id建立了索引的话,那么性能将会更好。那为什么在这种情况下使用JOIN会更有效率呢。因为MySQL不需要在内存中创建临时表来完成这个逻辑上需要两个步骤的查询工作。

优化OR条件
  对于含有OR的查询子句,如果要利用索引,则OR之间的每个条件列都必须用到索引;如果没有索引,则考虑增加索引。

使用SQL提示
  SQL 提示(SQL HINT)是优化数据库的一个重要手段,简单来说就是在SQL语句中加入一些人为的提示来达到优化的操作的目的。
例如:
引用

   SELECT SQL_BUFFER_RESULTS * FROM ...

这个语句将强制MySQL生成一个临时结果集。只要临时结果集生成后,所有表上的锁定均被释放。这能在遇到表锁定问题时或者要花很长时间将结果传给客户端时所帮助,因为可以尽快释放锁资源,
  下面是一些在MySQL中常用的SQL提示。
引用

  1. USE INDEX
   在查询语句中表名的后面,添加USE INDEX 来提供希望MySQL去参考的索引列表,就可以让MySQL不再考虑其他可用的索引。
    
引用

       explain select * from sales2 use index (ind_sales2_id) where id  3 \G;
   


2. IGNORE INDEX
     如果用户只是单纯地想让MySQL忽略一个或者多个索引,则可以使用IGNORE INDEX 作为HINT

3. FORCE INDEX
  为强制MySQL使用一个特定的索引,可在查询中使用FORCE INDEX作为HINT。例如当不强制使用索引的时候,因为id的值都是大于0的,因为MySQL会默认进行全表扫描,而不使用索引。例如:
引用

  expalin select * from sales2 where id > 0 \G;

但是,当使用FORCE INDEX进行提示时,即便使用索引的效率不是很高,MySQL还是选择使用了索引,这是MySQL留给用户的一个自行选择执行计划的权利。加入FORCE INDEX提示后在执行上面的SQL
引用

    explain select * from sales2 force index(index_sales2_id) where id > 0 \G;




  SQL优化问题是数据库性能优化最基础也是最重要的一个问题,实践表明很多数据库性能问题都是由于不合适的SQL语句造成。一些列的SQL优化描述。怎么定位问题,怎么在编写的时候优化,怎么来应对。不过优化SQL语句经常需要考虑的几个方面,比如索引,表分析,排序等等。
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics