order by 原理和优化

转载于https://blog.csdn.net/u013308135/article/details/76796770/

原理

  1. 利用索引的有序性获取有序数据
  2. 利用内存/磁盘文件排序获取结果 
    1) 双路排序:是首先根据相应的条件取出相应的排序字段和可以直接定位行数据的行指针信息,然后在sort buffer 中进行排序。 
    2)单路排序:是一次性取出满足条件行的所有字段,然后在sort buffer中进行排序。

优化方式

  1. 给order by 字段增加索引,orderby的字段必须在最前面设置 
    接下来给来说一下orderby什么时候使用索引和什么时候不使用索引的情况 
    1.使用索引情况

    1. SELECT id from form_entity order by name(给name建立索引) 
      当select 的字段包含在索引中时,能利用到索引排序功能,进行覆盖索引扫描,使用select * 则不能利用覆盖索引扫描且由于where语句没有具体条件MySQL选择了全表扫描且进行了排序操作。
    2. SELECT * from form_entity where name =’123’ and category_id=’1’ order by comment desc(name,comment建立复合索引) 
      组合索引中的一部分做等值查询 ,另一部分作为排序字段
    3. SELECT comment from form_entity group by name,comment order by name (name,comment建立复合索引)

    2.不使用索引情况

    1. SELECT id,comment from form_entity order by name(给name建立索引,comment没有索引)
    2. SELECT * from form_entity order by name(给name设置索引)
    3. SELECT * from form_entity order by name desc,comment desc(name,comment建立复合索引)
    4. SELECT * from form_entity where comment =’123’ order by name desc(name,comment建立复合索引)
    5. SELECT name from form_entity where category_id =’123’ order by name desc,comment desc(name,comment建立复合索引,category_id独立索引) 
      当查询条件使用了与order by不同的索引,但排序字段是另一个联合索引的非连续部分
    6. SELECT comment from form_entity group by name order by name ,comment(name,comment建立复合索引)
    7. 返回数据量过大也会不使用索引
    8. 排序非驱动表不会走索引
    9. order by 字段使用了表达式
  2. 去掉不必要的返回字段

  3. 增大 sort_buffer_size 参数设置

猜你喜欢

转载自blog.csdn.net/csdn_9527666/article/details/80792466