查询性能 - select 仅当存在时
Query performance - select only if exists
我正在努力提高查询效率。这是逐行检查,很多时候由于没有匹配的记录,查询不会到达更新点。我 (EDIT) know 认为最好的方法是先检查是否存在匹配项,然后再执行查询。以下面的真实案例为例,我试图将性能成本降至最低:
/* 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 个内部连接,但如果有更多会怎样)来查找记录是否匹配,然后再次将它们连接在一起以执行更新查询。在我使用的小型数据集中,这没什么大不了的。但是,如果这种逐行检查应该执行数百万次怎么办?
我相信应该有更有效的方法来创建此语句?有人有什么想法吗?
谢谢。
but what I dislike is the fact that I actually copy-paste the same
query over again - and within a T-SQL with 6 times a check like this,
it becomes very big
我认为您应该再次使用 Merge.Using 合并减少那些重复查询,并且 again.And 性能方面至少会比以前的代码更好。
这只是演示。
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;
这个应该没问题:
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
我正在努力提高查询效率。这是逐行检查,很多时候由于没有匹配的记录,查询不会到达更新点。我 (EDIT) know 认为最好的方法是先检查是否存在匹配项,然后再执行查询。以下面的真实案例为例,我试图将性能成本降至最低:
/* 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 个内部连接,但如果有更多会怎样)来查找记录是否匹配,然后再次将它们连接在一起以执行更新查询。在我使用的小型数据集中,这没什么大不了的。但是,如果这种逐行检查应该执行数百万次怎么办?
我相信应该有更有效的方法来创建此语句?有人有什么想法吗?
谢谢。
but what I dislike is the fact that I actually copy-paste the same query over again - and within a T-SQL with 6 times a check like this, it becomes very big
我认为您应该再次使用 Merge.Using 合并减少那些重复查询,并且 again.And 性能方面至少会比以前的代码更好。
这只是演示。
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;
这个应该没问题:
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