zoukankan      html  css  js  c++  java
  • 子查询,连接查询,在SQL2008R2中性能如何?

    以前或多或少的听说过,能用子查询的地方改用连接查询,性能有提升,如下的伪代码

    select *  from tab1 where col1 in (select col1 from tab2)
    select * from tab1 inner join tab2 on tab1.col1=tab2.col2

    这种使用连接查询代替子查询的写法,据说在SQL2000中有效果,我没有测试过,这次测试一下在SQL2008R2中的性能如何?

    首先看看独立子查询的逻辑读:

    SET STATISTICS IO ON;
    
    USE AdventureWorks
    GO
    
    DBCC FREEPROCCACHE
    CHECKPOINT
    DBCC DROPCLEANBUFFERS
    
    
    SELECT count(*) FROM sales.SalesOrderHeader AS soh
    WHERE soh.SalesOrderID IN
                            (
                                SELECT SalesOrderID FROM sales.salesOrderDetail AS sod
                                WHERE OrderQty>1
                                AND sod.ProductID IN
                                (
                                    SELECT ProductID FROM Production.product AS p
                                    WHERE p.color=N'red'
                                )
                            )
        

    这段代码的逻辑读为:

    (1 row(s) affected)
    Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
    Table 'SalesOrderHeader'. Scan count 1, logical reads 45, physical reads 2, read-ahead reads 43, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
    Table 'SalesOrderDetail'. Scan count 1, logical reads 1238, physical reads 35, read-ahead reads 1233, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
    Table 'Product'. Scan count 1, logical reads 15, physical reads 4, read-ahead reads 20, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

    再来看看使用连接查询的逻辑读:

    DBCC FREEPROCCACHE
    CHECKPOINT
    DBCC DROPCLEANBUFFERS
    
    SELECT count(DISTINCT soh.salesorderid)
    FROM sales.salesorderheader AS soh
    JOIN sales.salesorderdetail AS sod
    ON soh.salesorderid=sod.salesorderid
    AND sod.orderqty>1
    JOIN production.product AS p ON
    sod.productid=p.productid
    AND p.color=N'red'

    这段代码的逻辑读为:

    (1 row(s) affected)
    Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
    Table 'SalesOrderHeader'. Scan count 1, logical reads 45, physical reads 2, read-ahead reads 43, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
    Table 'SalesOrderDetail'. Scan count 1, logical reads 1238, physical reads 35, read-ahead reads 1233, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
    Table 'Product'. Scan count 1, logical reads 15, physical reads 4, read-ahead reads 20, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

    另外看看连接查询的第二种写法,把color=N’red'放入where 子句中

    DBCC FREEPROCCACHE
    CHECKPOINT
    DBCC DROPCLEANBUFFERS
    
    SELECT count(DISTINCT soh.salesorderid)
    FROM sales.salesorderheader AS soh
    JOIN sales.salesorderdetail AS sod
    ON soh.salesorderid=sod.salesorderid
    AND sod.orderqty>1
    JOIN production.product AS p 
    ON sod.productid=p.productid
    WHERE p.color=N'red'

    这段代码的逻辑读为:

    (1 row(s) affected)
    Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
    Table 'SalesOrderHeader'. Scan count 1, logical reads 45, physical reads 2, read-ahead reads 43, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
    Table 'SalesOrderDetail'. Scan count 1, logical reads 1238, physical reads 34, read-ahead reads 1233, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
    Table 'Product'. Scan count 1, logical reads 15, physical reads 4, read-ahead reads 20, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

    可以看到这三段代码的逻辑读是一样的,性能上没有任何的区别,看看从上到下三段代码的执行计划:

    image

    从上可以得到的结论:

    1:SQLSERVER引擎优化器已足够聪明,知道这三种写法没有任何的区别,所以大家怎么写还是按照自己的习惯来

    2:对于查询是这样,对于UPDATE/DELETE也是如此,子查询和连接查询在SQL2008中没有任何的区别!!

  • 相关阅读:
    ES5 ES6 作用域声明部分
    js 内建函数reduce
    $apply的使用与否
    得分-星星
    CSS3中translate、transform和translation的区别和联系
    vue 学习笔记
    -webkit-line-clamp 多行文字溢出...
    八位二进制数为什么表示范围(-128~~+127)理解
    vs2017_enterprise正式版离线安装包bt下载
    RSA密钥之C#格式与Java格式转换
  • 原文地址:https://www.cnblogs.com/fly_zj/p/2633970.html
Copyright © 2011-2022 走看看