在提高 SQL 查询的查询性能方面需要帮助
Need help in improving query performance of SQL Query
存储过程 return 结果花费的时间太长,我想提高存储过程的性能。但我不确定问题到底发生在哪里。谁能帮忙重写 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)
)
在没有任何其他信息的情况下,我建议将 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
通常会破坏 JOIN
的性能。
然后确保您在所有 JOIN
键上都有索引。
试试下面的查询,
EXISTS 子句和 OR 子句的主要问题
由于 OR 子句中的条件之一是变量,我们可以将代码分为两部分,并且不需要在同一查询中同时具有 IS NULL 和 exists 逻辑。
最好将 exists 子句中的连接列加载到 temp table 中,并且使用 major table 进行内部连接可能会提供更好的性能。
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
存储过程 return 结果花费的时间太长,我想提高存储过程的性能。但我不确定问题到底发生在哪里。谁能帮忙重写 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)
)
在没有任何其他信息的情况下,我建议将 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
通常会破坏 JOIN
的性能。
然后确保您在所有 JOIN
键上都有索引。
试试下面的查询, EXISTS 子句和 OR 子句的主要问题
由于 OR 子句中的条件之一是变量,我们可以将代码分为两部分,并且不需要在同一查询中同时具有 IS NULL 和 exists 逻辑。 最好将 exists 子句中的连接列加载到 temp table 中,并且使用 major table 进行内部连接可能会提供更好的性能。
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