由于子选择导致查询缓慢



>我有几个SQL Server 2014查询,这些查询会拉回一个数据集,我们需要在其中获取相关但不同的条件以及该数据的计数。我们使用子查询来做到这一点,但这会大大减慢它的速度。到目前为止,我们在数据库中获得更多数据可以依靠,这很好。 下面是查询:

SELECT 
T.*, 
ISNULL((SELECT COUNT(1)
FROM EventRegTix ERT, EventReg ER
WHERE ER.EventRegID = ERT.EventRegID 
AND ERT.TicketID = T.TicketID
AND ER.OrderCompleteFlag = 1), 0) AS NumTicketsSold
FROM 
Tickets T 
WHERE 
T.EventID = 12345
AND T.DeleteFlag = 0 
AND T.ActiveFlag = 1
ORDER BY 
T.OrderNumber ASC

我很确定这主要是由于子查询之外与Tickets表的关系。如果我将T.TicketID更改为实际的票证#(例如 999(,查询速度要快得多。

我试图将这些查询合并为一个,但由于子查询中还有其他字段,我无法让它正常工作。我在玩

COUNT(1) OVER (PARTITION BY T.TicketID) AS NumTicketsSold

但也想不通。

任何帮助将不胜感激!

我会把它写成:

SELECT T.*, 
(SELECT COUNT(1)
FROM EventRegTix ERT JOIN
EventReg ER
ON ER.EventRegID = ERT.EventRegID 
WHERE ERT.TicketID = T.TicketID AND ER.OrderCompleteFlag = 1
) AS NumTicketsSold
FROM Tickets T 
WHERE T.EventID = 12345 AND
T.DeleteFlag = 0 AND
T.ActiveFlag = 1
ORDER BY T.OrderNumber ASC;

正确、明确、标准的JOIN语法不会提高性能;它只是正确的语法。COUNT(*)无法返回NULL值,因此不需要COALESCE()或类似的函数。

您需要索引。 显而易见的是Tickets(EventID, DeleteFlag, ActiveFlag, OrderNumber)EventRegTix(TicketID, EventRegID)EventReg(EventRegID, OrderCompleteFlag)

我会尝试使用OUTER APPLY

SELECT T.*, T1.*
FROM Tickets T OUTER APPLY
(SELECT COUNT(1) AS NumTicketsSold
FROM EventRegTix ERT JOIN
EventReg ER
ON ER.EventRegID = ERT.EventRegID 
WHERE ERT.TicketID = T.TicketID AND ER.OrderCompleteFlag = 1
) T1
WHERE T.EventID = 12345 AND
T.DeleteFlag = 0 AND
T.ActiveFlag = 1
ORDER BY T.OrderNumber ASC;

而且,很明显,您需要Tickets(EventID, DeleteFlag, ActiveFlag, OrderNumber), EventRegTix(TicketID, EventRegID), and EventReg(EventRegID, OrderCompleteFlag)索引才能获得性能。

修复了此问题 - 查询从 5+ 秒变为 1/2 秒或更短。 问题是:

1(没有索引。 不知道所有FK字段也需要索引。 我索引了我们加入或位于 WHERE 子句中的所有字段。

2(使用SQL执行计划查看瓶颈所在位置。 告诉我没有索引,因此上面 1(!:)

感谢您所有的帮助,希望这篇文章可以帮助其他人。

丹尼斯

PS:语法也变了!

最新更新