• 关于SQL IO的一些资料


        前些天在做优化的时候发现一个有意思的现象,单纯的SQL执行很快,秒级返回,但是页面响应却很慢,一直在想这是为什么呢?有点怀疑服务器的IO有问题,想了想做了个实验,模拟了同样的场景,通过优化SQL将查询带来的IO开销降低了7到8倍的样子,页面响应果然得到了很大的提升。对于SQL的IO我没什么太多的研究,这里罗列一些东西,权当是为以后的深入研究做个资料的收集吧。园子里有很多关于SQL IO 的介绍,写的都很不错,说实话有很多看的我云里雾里的,故退而其次写一些皮毛的东西。这里只讲现象,不讲故事,场景也不一定完全的合理,具体的情况还得具体对待,不可对号入座哦。

           怎么才能降低SQL所带来的IO开销呢?仁者见仁智者见智,下面我列一些常见的查询方式:

    • 表连接与子查询

      

      2个表结构如图,CustomerID做为关联键,左表记录100W左右,右表:5条,下面是我们比较常见的2个查询语句:  

    查询A:
    SET STATISTICS IO ON 
    SELECT *,b.phone FROM dbo.Customers a LEFT JOIN  dbo.CustomerDetial b ON  a.CustomerID=b.CustomerID
    
    对应的额IO
    (1000002 行受影响)
    表'CustomerDetial'。扫描计数1,逻辑读取3 次,物理读取0 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。
    表'Customers'。扫描计数1,逻辑读取6954 次,物理读取0 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。
    
    
    查询B:
    SET STATISTICS IO ON
    SELECT*,(SELECT phone FROM dbo.CustomerDetial WHERE Customerid=a.CustomerID) phone FROM dbo.Customers a
    
    对应的额IO
    (1000002 行受影响)
    表'CustomerDetial'。扫描计数1000002,逻辑读取3000006 次,物理读取0 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。
    表'Customers'。扫描计数1,逻辑读取6954 次,物理读取0 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。
    

      从这个列子我们可以看到子查询付出的IO开销远远大于表连接,一般情况下能使用表连接则不要用子查询,当然这个不是一定的,还是要具体情况具体分析。

    • Exists、innerjoin、in

      这三者的使用也比较常见,建议的使用优先级inner join—> Exists—>in

    • OR 语句

      建议使用Union来替换

    • 有效使用索引

      有效使用索引可以降低索引扫描和表扫描带来的IO开销,特别要注意的是复合索引、覆盖索引的使用

    • 减少查询的列数、记录数

      今天先到这里,后续继续补充。同时欢迎看到该文章的朋友提供资料。

  • 相关阅读:
    ThinkPHP5+jQuery+MySql实现投票功能
    JQ input输入框回车生成标签,可删除,并获取标签的值
    php 使用 CURL 获取数据
    new String创建了几个对象
    java高级开发面试总结
    使用 Sublime Text 将含下划线的字符串批量替换为驼峰命名法格式的字符串
    Synchronized方法锁、对象锁、类锁区别
    利用Redisson实现分布式锁及其底层原理解析
    MySQL索引
    JVM常见面试题
  • 原文地址:https://www.cnblogs.com/mfkaudx/p/3490640.html
Copyright © 2020-2023  润新知