>我有几个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:语法也变了!