关于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开销,特别要注意的是复合索引、覆盖索引的使用

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

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

原文地址:https://www.cnblogs.com/mfkaudx/p/3490640.html