子查询和排序优化

子查询优化

        子查询可以一次性完成很多逻辑上需要多个步骤才能完成的SQL操作; 但是,子查询的执行效率不高 原因如下:
  • 执行子查询时,MySQL需要为内层查询语句的执行结果建立一个临时表 ,外层查询语句从临时表中查询记录。查询完毕后,再撤销这些临时表 。这样会消耗过多的CPU和IO资源,产生大量的慢查询;
  • 子查询的结果集存储的临时表,不论是内存临时表还是磁盘临时表都不会存在索引 ,所以查询性能会受到一定的影响;

        在MySQL中,可以使用连接(JOIN)查询来替代子查询。连接查询 不需要建立临时表 ,其速度比子查询快 ,如果查询中使用索引的话,性能就会更好;

 排序优化

        问题: WHERE 条件字段上加索引,但是为什么在 ORDER BY 字段上还要加索引呢?

        优化建议:

  • SQL 中,可以在 WHERE 子句和 ORDER BY 子句中使用索引,目的是在 WHERE 子句中 避免全表扫描 ,在 ORDER BY 子句 避免使用 FileSort 排序 。当然,某些情况下全表扫描,或者 FileSort 排序不一定比索引慢。总的来说,还是要避免,提高效率;
  • 尽量使用 索引 完成 ORDER BY 排序。如果 WHERE ORDER BY 后面是相同的列就使用单索引列; 如果不同就使用联合索引;
  • 无法使用 索引 时,需要对 FileSort 方式进行调优;

        结论:
  • type 是 ALL,最坏的情况。Extra 里出现了 Using filesort,也是最坏的情况;
  • 两个索引同时存在,mysql自动选择最优的方案;
  • 当【范围条件】和【group by 或者 order by】的字段出现二选一时,优先观察条件字段的过
    滤数量,如果过滤的数据足够多,而需要排序的数据并不多时,优先把索引放在范围字段上。反之,亦然;

 filesort算法:双路排序和单路排序(了解)

        双路排序 (慢)
  • MySQL 4.1之前是使用双路排序 ,字面意思就是两次扫描磁盘,最终得到数据, 读取行指针和order by列 ,对他们进行排序,然后扫描已经排序好的列表,按照列表中的值重新从列表中读取对应的数据输出
  • 从磁盘取排序字段,在buffer进行排序,再从 磁盘取其他字段
        取一批数据,要对磁盘进行两次扫描,IO很耗时,所以在mysql4.1之后,出现了单路排序。
        单路排序 (快)
        从磁盘读取查询需要的 所有列 ,按照order by列在buffer对它们进行排序,然后扫描排序后的列表进行输出,它的效率更快一些,避免了第二次读取数据。并且把随机IO变成了顺序IO,但它会使用更多的空间,因为它把每一行都保存在内存中了。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值