在提高 SQL Query 的查询性能方面需要帮助

Posted

技术标签:

【中文标题】在提高 SQL Query 的查询性能方面需要帮助【英文标题】:Need help in improving query performance of SQL Query 【发布时间】:2021-06-10 11:54:57 【问题描述】:

存储过程返回结果的时间过长,我想提高存储过程的性能。但我不确定问题到底发生在哪里。任何人都可以通过在 EXISTS 子句之后重写子查询来提供帮助。

仅供参考,这些表有数十万条记录

DECLARE @InvNo VARCHAR(MAX) = NULL,

SELECT @InvNo='123'

DECLARE @tblInv TABLE (RowID INT IDENTITY(1,1) PRIMARY KEY CLUSTERED,
                         InvNo VARCHAR(MAX))

IF @InvNo IS NOT NULL
    INSERT INTO @tblInv(InvNo)
    SELECT value
      FROM STRING_SPLIT(@InvNo,',')

 
select * from table1 t
where (@InvNo IS NULL
           OR EXISTS (SELECT 1
                          FROM @tblInv i
                    INNER JOIN table2 inv   
                            ON inv.inv_no = i.InvNo OR ISNULL(inv.alt_inv_no,'@@') = i.InvNo                                
                    INNER JOIN table3 isp
                            ON isp.inv_no = inv.inv_no
                    INNER JOIN table4 ic
                            ON ic.inv_no = inv.inv_no                                               
                         WHERE isp.bl_no = t.bl_no
                           AND ic.cust_code = t.cust_code) 
                )

【问题讨论】:

我们仍然缺少我们在您的last question 中询问您的执行计划。另外,什么是“十万”? 问题可能是子查询中的OR OR ISNULL(inv.alt_inv_no,'@@') 不会是 SARGable。使用IS NULLIS NOT NULL 正确处理您的NULL 值。你真的也需要EXISTS 中的所有JOIN 吗? @Larnu 是的,我真的需要那些 JOINS。如果 InvNo 具有单个值或无值,则删除 OR 并添加一个额外的 EXISTS 似乎对我有用。对于逗号分隔的值,查询再次变慢了。。 请记住,我们大多数不是来自印度的人都不知道“lac”是什么。 【参考方案1】:

在没有任何其他信息的情况下,我建议将 exists 拆分为两个单独的条件:

select *
from table1 t
where @InvNo IS NULL OR
      EXISTS (SELECT 1
              FROM @tblInv i JOIN
                   table2 inv   
                   ON inv.inv_no = i.InvNo JOIN                              
                   table3 isp
                   ON isp.inv_no = inv.inv_no JOIN
                   table4 ic
                   ON ic.inv_no = inv.inv_no                                               
              WHERE isp.bl_no = t.bl_no AND ic.cust_code = t.cust_code 
             ) OR
     EXISTS (SELECT 1
              FROM @tblInv i JOIN
                   table2 inv   
                   ON inv.alt_inv_no = i.InvNo JOIN                              
                   table3 isp
                   ON isp.inv_no = inv.inv_no JOIN
                   table4 ic
                   ON ic.inv_no = inv.inv_no                                               
              WHERE isp.bl_no = t.bl_no AND ic.cust_code = t.cust_code 
             );

OR 通常会扼杀JOINs 的性能。

然后确保您对所有 JOIN 键都有索引。

【讨论】:

谢谢你,戈登。你是个天才。你救了我。你是对的.. OR 是罪魁祸首。 :) 根据您的建议,性能会更好。但如果@InvNo 是逗号分隔值,则时间再次比原始查询长:( @ArpitaDutta 。 . . (1) 逗号分隔值通常只是一个问题,您不应该使用它们。 (2) 这回答了您在这里提出的问题。如果您有不同的问题,请提出一个问题,并明确与该问题的不同之处。【参考方案2】:

试试下面的查询, EXISTS 子句和 OR 子句的主要问题

由于 OR 子句中的条件之一是变量,我们可以将代码分为两部分,并且不需要在同一个查询中同时具有 IS NULL 和存在逻辑。 将exists子句中的连接列加载到临时表中会很好,与主表的内部连接可能会提供更好的性能。

SELECT @InvNo='123'

DECLARE @tblInv TABLE 
(RowID INT IDENTITY(1,1) PRIMARY KEY CLUSTERED, InvNo VARCHAR(MAX))
     
IF @InvNo IS NULL
BEGIN
    select * from table1 t
END
ELSE
BEGIN
    INSERT INTO @tblInv(InvNo)
    SELECT value FROM STRING_SPLIT(@InvNo,',')
    
SELECT DISTINCT isp.bl_no,ic.cust_code INTO #T
      FROM @tblInv i
    INNER JOIN table2 inv   
            ON inv.inv_no = i.InvNo                              
    INNER JOIN table3 isp
            ON isp.inv_no = inv.inv_no
    INNER JOIN table4 ic
            ON ic.inv_no = inv.inv_no
UNION
SELECT DISTINCT isp.bl_no,ic.cust_code
      FROM @tblInv i
    INNER JOIN table2 inv   
            ON ISNULL(inv.alt_inv_no,'@@') = i.InvNo                                
    INNER JOIN table3 isp
            ON isp.inv_no = inv.inv_no
    INNER JOIN table4 ic
            ON ic.inv_no = inv.inv_no

    select * from table1 t
    INNER JOIN #T T2 ON T2.bl_no = t.bl_no AND T2.cust_code = t.cust_code
END

【讨论】:

感谢您的解决方案。但是我提到的查询只是包含许多其他查询的巨大存储过程的一部分。我不能像你建议的那样重写它。 :(

以上是关于在提高 SQL Query 的查询性能方面需要帮助的主要内容,如果未能解决你的问题,请参考以下文章

如何提高 Sql server 中 Distinct Query 的性能

提高 self-JOIN SQL Query 性能

如何提高 SQL Server 查询的性能 [关闭]

提高分层 SQL 结构的性能

MySql的概述及入门

如何提高风数据SQL查询性能