改進/優化SQL Server中的LEFT JOIN

[英]Improve/optimize LEFT JOIN in SQL Server


I have a decently long (10 tables, about 60k records each) query, all of those tables are joined using a left join since they could contain null values (all of them).

我有一個相當長的(10個表,每個約60k記錄)查詢,所有這些表都使用左連接連接,因為它們可以包含空值(所有這些)。

I'm seeing a huge performance hit and I tracked it down to this bit of code.

我看到了巨大的性能損失,我將其跟蹤到這段代碼。

SELECT * 
FROM MAIN_TABLE d 
LEFT JOIN INSURANCES i on i.IMREDEM_CODE = d.IMREDEM_CODE 
                      and i.INS_TERMINATIONDATE IS NULL 
                      and INS_RANK = 0
                      and i.IMREINS_CODE = (SELECT TOP 1 IMREINS_CODE 
                                              from INSURANCES i2
                                             WHERE i2.IMREDEM_CODE = i.IMREDEM_CODE 
                                               and i2.INS_TERMINATIONDATE IS NULL 
                                               and i2.INS_RANK = 0
                                          ORDER BY TAG_SYSTEMDATE DESC)

Basically what I am needing to do is that the insurance table could contain 0 or many records because when they update the insurance it performs an insert not an update for audit purposes. So I have to join the table twice, on a left join. Further I need to do this query twice for primary and secondary insurance (primary is rank = 0 and secondary is rank =1. The IMREDEM_CODE is a PK for the D table and a FK for the i table.

基本上我需要做的是保險表可以包含0或許多記錄,因為當他們更新保險時,它執行插入而不是更新以用於審計目的。所以我必須在左邊的連接上加入桌子兩次。此外,我需要對主要和次要保險兩次執行此查詢(主要是rank = 0,secondary是rank = 1.IMREDEM_CODE是D表的PK和i表的FK。

The answer is here:

答案在這里:

left join INSURANCES i on i.IMREDEM_CODE = d.IMREDEM_CODE 
and i.IMREINS_CODE = (SELECT max(imreins_code) FROM INSURANCES i2  WHERE i2.IMREDEM_CODE = i.IMREDEM_CODE and i2.INS_TERMINATIONDATE IS NULL and i2.INS_RANK = 0)

2 个解决方案

#1


2  

While I'm sure you may be able to optimize this even further, I have taken a quick stab at it. Your execution plan will do 3 Table Scans. You can try this which will reduce that to 2:

雖然我相信你可以進一步優化它,但我已經快速嘗試了。您的執行計划將執行3次表掃描。你可以嘗試這個,將其減少到2:

SELECT *
FROM Main_Table d
    LEFT JOIN 
        (SELECT TOP 1 *
         FROM Insurances 
         WHERE INS_TERMINATIONDATE IS NULL 
             AND INS_RANK = 0
         ORDER BY TAG_SYSTEMDATE DESC) i on i.IMREDEM_CODE = d.IMREDEM_CODE;

There is probably a better approach than TOP 1 and Order By, but I'm getting tired and can't think of it at the moment. Either way, this is definitely more efficient.

可能有比TOP 1和Order By更好的方法,但是我已經厭倦了,現在想不到它。無論哪種方式,這肯定更有效率。

Here is the SQL Fiddle with both sets of queries. You can see the execution plan in each.

這是兩個查詢集的SQL小提琴。您可以在每個中查看執行計划。

Good luck.

#2


1  

I believe the following will give you exactly the same result but faster;

我相信以下內容會給你完全相同但更快的結果;

  SELECT * 
     FROM MAIN_TABLE d 
LEFT JOIN INSURANCES i on i.IMREDEM_CODE = d.IMREDEM_CODE 
                      and i.IMREINS_CODE = select max(i.imreins_code) from INSURANCES
                      and i.INS_TERMINATIONDATE IS NULL
                      and i.INS_RANK = 0

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2013/01/19/729fd7116cc66a45079f586fa9cdf067.html



 
粤ICP备14056181号  © 2014-2020 ITdaan.com