Sql 由于子选择,查询速度较慢

Sql 由于子选择,查询速度较慢,sql,sql-server,tsql,sql-server-2014,Sql,Sql Server,Tsql,Sql Server 2014,我有几个SQL Server 2014查询,这些查询提取了一个数据集,在该数据集中,我们需要获得与该数据相关但标准不同的计数。我们通过一个子查询来实现这一点,但这大大降低了它的速度。到目前为止一切都很好,我们在数据库中获得了更多的数据。以下是查询: SELECT T.*, ISNULL((SELECT COUNT(1) FROM EventRegTix ERT, EventReg ER WHERE ER.EventRegID =

我有几个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
更改为实际的ticket#(例如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;
正确、明确、标准的
联接
语法不会提高性能;这就是正确的语法
COUNT(*)
无法返回
NULL
值,因此不需要
COALESCE()
或类似的函数

你需要索引。最明显的是
Tickets(EventID,DeleteFlag,ActiveFlag,OrderNumber)
EventRegTix(TicketID,EventRegID)
,和
EventReg(EventRegID,OrderCompleteFlag)

我将其写成:

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;
正确、明确、标准的
联接
语法不会提高性能;这就是正确的语法
COUNT(*)
无法返回
NULL
值,因此不需要
COALESCE()
或类似的函数


你需要索引。最明显的是
Tickets(EventID、DeleteFlag、ActiveFlag、OrderNumber)
EventRegTix(TicketID、EventRegID)
,以及
EventReg(EventRegID、OrderCompleteFlag)
我会尝试使用
外部应用

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;

而且,显然您需要索引
票证(EventID、DeleteFlag、ActiveFlag、OrderNumber)、EventRegTix(TicketID、EventRegID)和EventReg(EventRegID、OrderCompleteFlag)
来获得性能。

我会尝试使用
外部应用

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;

显然,您需要索引
票证(EventID、DeleteFlag、ActiveFlag、OrderNumber)、EventRegTix(TicketID、EventRegID)和EventReg(EventRegID、OrderCompleteFlag)
来获得性能。

修复了此问题-查询时间从5秒以上缩短到1/2秒或更短。问题是:

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

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

谢谢你们的帮助,希望这篇文章能帮助其他人

丹尼斯


PS:也更改了语法

修复了此问题-查询时间从5秒以上缩短到1/2秒或更短。问题是:

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

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

谢谢你们的帮助,希望这篇文章能帮助其他人

丹尼斯



PS:也更改了语法

什么版本的SQL Server?为什么不简单地将连接保留到EventRegTix和EventReg,而不是子查询。此外,您真的应该开始使用ANSI-92样式联接。它们已经存在了25年多了。旁注:这种老式的连接语法已经有25年的历史了。应该使用新样式联接。(从表A作为内部联接表B作为A.Id=B.Id…)您可以发布执行计划吗?执行计划指出了问题-EventRegID的EventRegTix表上没有索引(它是一个FK)。现在索引。。。很快。非常感谢。什么版本的SQL Server?为什么不简单地将连接保留到EventRegTix和EventReg,而不是子查询。此外,您真的应该开始使用ANSI-92样式联接。它们已经存在了25年多了。旁注:这种老式的连接语法已经有25年的历史了。应该使用新样式联接。(从表A作为内部联接表B作为A.Id=B.Id…)您可以发布执行计划吗?执行计划指出了问题-EventRegID的EventRegTix表上没有索引(它是一个FK)。现在索引。。。很快。非常感谢。“您需要索引。”此查询不会更快。我不知道还有什么可以索引??“你需要索引。”这个查询没有更快。我不知道还需要索引什么??您是否需要对任何有条件的字段进行索引?我不是DBA(!!),但我不认为真/假字段需要索引。这是我可能错过的一个。FK的索引是默认的还是仅仅是PK?呃,我想这是我的问题。默认情况下,FK没有索引,让我索引并返回到这个问题。谢谢您是否需要任何字段上的索引,这些字段都有相应的条件?我不是DBA(!!),但我不认为真/假字段需要索引。这是我可能错过的一个。FK的索引是默认的还是仅仅是PK?呃,我想这是我的问题。默认情况下,FK没有索引,让我索引并返回到这个问题。谢谢您可能需要阅读和包含的列。是的,将进行审阅您可能需要阅读和包含的列。是的,将进行审阅