• 子查询,连接查询,在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中没有任何的区别!!

  • 相关阅读:
    php笔记之数组
    php笔记之函数
    vue笔记之路由
    <QT>:使用QUdpSocket进行UDP通信
    Linux下用ssh在远程Xserver上显示图形界面
    <学习QT>在QListWidget中实现每个单元项显示文字在上图片在下
    const限定符以及顶层const和底层const的理解
    了解X window以及相关知识
    Linux下使用Eclipse C/C++生成创建并调用动态库(.so)
    Linux下搭载Xwindow(Xlib)开发环境
  • 原文地址:https://www.cnblogs.com/fly_zj/p/2633970.html
Copyright © 2020-2023  润新知