我有几个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
但也无法弄清楚。
任何帮助将不胜感激!
答案 0 :(得分:5)
我会这样写:
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)
上。
答案 1 :(得分:1)
我会尝试使用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)
才能获得性能。
答案 2 :(得分:0)
解决了此问题-查询时间从5秒以上缩短到1/2秒或更短。问题是:
1)没有索引。也不知道所有FK字段都需要索引。我索引了所有我们加入或在WHERE子句中的字段。
2)使用SQL执行计划查看瓶颈所在的位置。告诉我没有索引,因此在1)以上! :)
感谢您的所有帮助人员,希望本文能对其他人有所帮助。
丹尼斯
PS:也更改了语法!