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).
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)
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:
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.
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