sql - 改进/优化 SQL Server 中的 LEFT JOIN

标签 sql sql-server sql-server-2008

我有一个相当长的(10 个表,每个大约 60k 条记录)查询,所有这些表都使用左连接进行连接,因为它们可能包含空值(所有这些)。

我看到了巨大的性能损失,我将其追溯到这段代码。

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)

基本上我需要做的是保险表可以包含 0 条或多条记录,因为当他们更新保险时,它执行插入而不是出于审计目的的更新。所以我必须两次加入表格,左加入。此外,我需要对主要和次要保险执行两次此查询(主要是 rank = 0,次要是 rank =1。IMREDEM_CODE 是 D 表的 PK 和 i 表的 FK。

答案在这里 :
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)

最佳答案

虽然我确信您可以进一步优化它,但我已经快速尝试了一下。您的执行计划将执行 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;

可能有比 TOP 1 和 Order By 更好的方法,但我累了,现在想不起来。无论哪种方式,这绝对是更有效的。

这是SQL Fiddle与两组查询。您可以在每个中看到执行计划。

祝你好运。

关于sql - 改进/优化 SQL Server 中的 LEFT JOIN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14410017/

相关文章:

javascript - HTML5 应用数据库同步

java - 如何使用 Hibernate/JDBC 删除函数?

sql-server - SQL Server 2016 始终加密证书停止工作,超时错误

sql-server - 在带有 sp_executesql 和参数的动态 SQL 中使用 NOT IN

sql - 在 SQL 中,如何允许参数中存在空值?

mysql - 使用 mdbtools 将 access db 转换为 sql

SQL Server 2000 : need to return record ID from a previous record in current query

c# - ADO.NET 连接导致实例失败

sql - 如何安排作业每天运行 SQL 查询?

php - 创建订阅功能(链接多个表?)?