Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2008 r2 使用IF EXISTS和内部存在性检查的性能有问题_Sql Server 2008 R2 - Fatal编程技术网

Sql server 2008 r2 使用IF EXISTS和内部存在性检查的性能有问题

Sql server 2008 r2 使用IF EXISTS和内部存在性检查的性能有问题,sql-server-2008-r2,Sql Server 2008 R2,这是在一个存储过程中..这个if语句,然后我做一些工作。@AsOfDate是日期数据类型的传入变量。我的问题是,为什么只有当整个语句都在IF-exists中时,才能通过删除最内部的exists来获得更好的性能 这两个表格: dbo.TXXX_InventoryDetail-13亿条记录..最新统计数据 dbo.TXXX_InventoryFull-980万条记录..最新统计数据 声明: if exists (select 1 from dbo.TXXX_Inventor

这是在一个存储过程中..这个if语句,然后我做一些工作。@AsOfDate是日期数据类型的传入变量。我的问题是,为什么只有当整个语句都在IF-exists中时,才能通过删除最内部的exists来获得更好的性能

这两个表格:

dbo.TXXX_InventoryDetail-13亿条记录..最新统计数据 dbo.TXXX_InventoryFull-980万条记录..最新统计数据 声明:

if exists (select 1
             from dbo.TXXX_InventoryDetail o
            where exists (select 1
                           from dbo.TXXX_InventoryFull i
                          where i.C001_AsOfDate= o.C001_AsOfDate
                            and i.C001_ProductID=o.C001_ProductID
                            and i.C001_StoreNumber=o.C001_StoreNumber
                            and i.C001_AsOfDate=@AsOfDate
                            and (i.C001_LastModelDate!=o.C001_LastModelDate
                                  or o.C001_InventoryQty!=o.C001_InventoryQty
                                  or i.C001_OnOrderQty!=o.C001_OnOrderQty
                                  or i.C001_TBOQty!=o.C001_TBOQty
                                  or i.C001_ModelQty!=o.C001_ModelQty
                                  or i.C001_TBOAdjustQty!=o.C001_TBOAdjustQty
                                  or i.C001_ReturnQtyPending!=o.C001_ReturnQtyPending
                                  or i.C001_ReturnQtyInProcess!=o.C001_ReturnQtyInProcess
                                  or i.C001_ReturnQtyDueOut!=o.C001_ReturnQtyDueOut))
              and o.C001_AsOfDate=@AsOfDate)
io输出:

表“TXXX_InventoryFull”。扫描计数9240262,逻辑读取29548864 表“T001\U库存详情”。扫描计数1,逻辑读取17259 如果删除存在的第二个连接并执行连接:

 if exists (select 1
             from dbo.TXXX_InventoryDetail o,
                  dbo.TXXX_InventoryFull i
            where i.C001_AsOfDate= o.C001_AsOfDate
                            and i.C001_ProductID=o.C001_ProductID
                            and i.C001_StoreNumber=o.C001_StoreNumber
                            and i.C001_AsOfDate=@AsOfDate
                            and (i.C001_LastModelDate!=o.C001_LastModelDate
                                  or o.C001_InventoryQty!=o.C001_InventoryQty
                                  or i.C001_OnOrderQty!=o.C001_OnOrderQty
                                  or i.C001_TBOQty!=o.C001_TBOQty
                                  or i.C001_ModelQty!=o.C001_ModelQty
                                  or i.C001_TBOAdjustQty!=o.C001_TBOAdjustQty
                                  or i.C001_ReturnQtyPending!=o.C001_ReturnQtyPending
                                  or i.C001_ReturnQtyInProcess!=o.C001_ReturnQtyInProcess
                                  or i.C001_ReturnQtyDueOut!=o.C001_ReturnQtyDueOut)
              and o.C001_AsOfDate=@AsOfDate)
io输出:

表“TXX\U库存详情”。扫描计数0,逻辑读取333952 表“TXXX_InventoryFull”。扫描计数1,逻辑读取630 现在..我认为它是if存在的原因是如果我删除它并进行如下选择计数*:

select COUNT(*)
             from dbo.T001_InventoryDetail o
            where exists (select 1
                           from dbo.TXXX_InventoryFull i
                          where i.C001_AsOfDate= o.C001_AsOfDate
                            and i.C001_ProductID=o.C001_ProductID
                            and i.C001_StoreNumber=o.C001_StoreNumber
                            and i.C001_AsOfDate=@AsOfDate
                            and (i.C001_LastModelDate!=o.C001_LastModelDate
                                  or o.C001_InventoryQty!=o.C001_InventoryQty
                                  or i.C001_OnOrderQty!=o.C001_OnOrderQty
                                  or i.C001_TBOQty!=o.C001_TBOQty
                                  or i.C001_ModelQty!=o.C001_ModelQty
                                  or i.C001_TBOAdjustQty!=o.C001_TBOAdjustQty
                                  or i.C001_ReturnQtyPending!=o.C001_ReturnQtyPending
                                  or i.C001_ReturnQtyInProcess!=o.C001_ReturnQtyInProcess
                                  or i.C001_ReturnQtyDueOut!=o.C001_ReturnQtyDueOut))
              and o.C001_AsOfDate=@AsOfDate
TXXX_库存已满'。扫描计数41,逻辑读取692 T001_库存详情”。扫描计数65,逻辑读取17477 “工作台”。扫描计数0,逻辑读取0
我猜当你使用join时,你得到的计划是完全不同的。也许行数的不平衡——外部表非常大,内部表较小——使优化器适合,但它可能更容易使用联接消除行——您可能会看到其他循环运算符使用更糟糕的查询。在看不到计划或无法复制的情况下,很难进行真正的猜测,但您应该始终以尽可能早地在计划中消除大多数行为目标。在计划的后期,通过几个运算符/子查询收回数百万行,而仅仅删除其中的大多数行,几乎肯定会产生更差的性能。

我在SQL 08 R2服务器上使用EXISTS语句时发现了类似的问题,在SQL 08和SQL 05上,完全相同的语句可以正常运行

我发现这种改变

WHILE EXISTS(SELECT * FROM X)
会非常慢,但是:

WHILE ISNULL((SELECT TOP 1 ID FROM X), 0) <> 0
又跑得非常快了


对我来说,这似乎是一个R2问题……

一般来说,应该避免在谓词中执行协调子查询,因为这些子查询往往会强制进行嵌套循环联接。在查询大型数据集时,尤其是在试图发现数据集之间的差异时,允许查询优化器在散列、合并和嵌套循环算法之间动态选择是很重要的,如果使用协调子查询构造查询,这可能是不可能的。最好在FROM子句中将这些表创建为派生表