查询性能 - 仅在存在时选择

时间:2015-02-05 12:37:30

标签: sql sql-server query-performance

我试图提高查询效率。这是一个逐行检查,由于没有匹配的记录,很多时候查询无法进入更新点。我(编辑) 知道认为最好的方法是首先检查是否匹配,然后执行查询。以下面的实例为例,我尝试将性能成本降至最低:

/* LOOPING FROM MIN(ID) TILL MAX(ID) */
IF EXISTS(SELECT *
            FROM InvoicesHC IHC
                INNER JOIN ContractSpecifications CS ON IHC.ContractSpecificationID = CS.ContractSpecificationID
                INNER JOIN InstalledProductGroups IPG ON IPG.InstalledProductGroupID = CS.InstalledProductGroupID
                INNER JOIN ProductGroups PG ON PG.ProductGroupID = IPG.ProductGroupID
                INNER JOIN ContractFinYears CFY ON IHC.ContractFinYearID = CFY.ContractFinYearID
            WHERE PG.ProductGroupID = 2 AND IHC.ContractNr = @CCODE AND CFY.ContractFinYear = @CYEAR)
    BEGIN
            UPDATE InvoicesHC SET InvoicePrice = @IGAS, PONumber = @POCO
            FROM InvoicesHC IHC
                INNER JOIN ContractSpecifications CS ON IHC.ContractSpecificationID = CS.ContractSpecificationID
                INNER JOIN InstalledProductGroups IPG ON IPG.InstalledProductGroupID = CS.InstalledProductGroupID
                INNER JOIN ProductGroups PG ON PG.ProductGroupID = IPG.ProductGroupID
                INNER JOIN ContractFinYears CFY ON IHC.ContractFinYearID = CFY.ContractFinYearID
            WHERE PG.ProductGroupID = 2 AND IHC.ContractNr = @CCODE AND CFY.ContractFinYear = @CYEAR
    END

所以我首先检查它是否存在,然后我实际执行它。这应该使查询运行得更快,但我不喜欢的事实是我实际上再次复制粘贴相同的查询 - 并且在T-SQL中进行6次这样的检查,它变得非常大 - 比它更大实际上应该看起来像我的意思。我的另一个问题是性能:我已经将表连接在一起(现在只有4个内连接,但如果还有更多内容)可以查找记录是否匹配,然后再将它们连接在一起进行更新查询。在我使用的小数据集中,这不是什么大问题。但是,如果这种逐行检查应该被执行数百万次呢?

我认为应该有一种更有效的方式来创建这种说法?有人有什么想法吗?

感谢。

2 个答案:

答案 0 :(得分:0)

  

但我不喜欢的事实是我实际上是复制粘贴相同的   再次查询 - 并在T-SQL中进行6次这样的检查,   它变得非常大

我认为你应该使用Merge.Using merge一次又一次地减少那些重复查询。性能明智至少会比早期的代码更好。

这只是演示。

MERGE InvoicesHC AS TRG
USING (
SELECT InvoicesHC
            FROM InvoicesHC IHC
                INNER JOIN ContractSpecifications CS ON IHC.ContractSpecificationID = CS.ContractSpecificationID
                INNER JOIN InstalledProductGroups IPG ON IPG.InstalledProductGroupID = CS.InstalledProductGroupID
                INNER JOIN ProductGroups PG ON PG.ProductGroupID = IPG.ProductGroupID
                INNER JOIN ContractFinYears CFY ON IHC.ContractFinYearID = CFY.ContractFinYearID
            WHERE PG.ProductGroupID = 2 AND IHC.ContractNr = @CCODE AND CFY.ContractFinYear = @CYEAR
)as SRC
on trg.ContractNr=src.ContractNr
When matched then
    update 
        SET InvoicePrice = @IGAS, PONumber = @POCO;

答案 1 :(得分:0)

这个应该没问题:

        UPDATE InvoicesHC SET InvoicePrice = @IGAS, PONumber = @POCO
        FROM InvoicesHC IHC
            INNER JOIN ContractSpecifications CS ON IHC.ContractSpecificationID = CS.ContractSpecificationID
            INNER JOIN InstalledProductGroups IPG ON IPG.InstalledProductGroupID = CS.InstalledProductGroupID
            INNER JOIN ProductGroups PG ON PG.ProductGroupID = IPG.ProductGroupID
            INNER JOIN ContractFinYears CFY ON IHC.ContractFinYearID = CFY.ContractFinYearID
        WHERE PG.ProductGroupID = 2 AND IHC.ContractNr = @CCODE AND CFY.ContractFinYear = @CYEAR