【问题标题】:SQL Server : stored procedure is slow when running two left join from one tableSQL Server:从一个表运行两个左连接时存储过程很慢
【发布时间】:2020-10-20 16:16:42
【问题描述】:

我有一个存储过程,它运行一个查询来获取一些行的数据 coupe,这些行不是那么大的表,它有两个来自同一个表的左连接,但运行速度很慢,并且需要 300 毫秒,每个表有 6 到 20 行表。

如何优化这个存储过程?

SELECT  
    m.MobileNotificationID,
    m.[Message] AS text, 
    m.TypeId AS typeId ,
    m.MobileNotificationID AS recordId ,
    0 badge ,
    m.DeviceID,
    ISNULL(users.DeviceToken, subscribers.DeviceToken) DeviceToken,
    ISNULL(users.DeviceTypeID, subscribers.DeviceTypeID) DeviceTypeID, 
    m.Notes,
    isSent = 0
    --, m.SubscriberID, m.UserID
FROM 
    MobileNotification m 
LEFT JOIN
    Device users ON m.userId = users.UserID 
                 AND users.DeviceID = m.DeviceID 
LEFT JOIN
    Device subscribers ON m.SubscriberID = subscribers.SubscriberId  
                       AND subscribers.DeviceID = m.DeviceID
WHERE 
    IsSent = 0 
    AND m.DateCreated <= (SELECT GETDATE()) 
    AND (0 = 0 OR ISNULL(users.DeviceTypeID, subscribers.DeviceTypeID) = 0)
    AND (ISNULL(users.DeviceToken, '') <> '' OR 
         ISNULL(subscribers.DeviceToken, '') <> '')
ORDER BY 
    m.DateCreated DESC

【问题讨论】:

  • 总之,每条记录都会存在于用户或订阅者上吗?更新您的原始问题,说明您想要什么以及为什么要进行所有这些 ISNULL() 检查。我还看到 ( 0=0 OR ... 这表明它是某种动态创建的 SQL 语句,因为 0=0 始终为真,并且无论其 (parens) 中该行的其余部分如何,都将始终返回。

标签: sql sql-server-2012


【解决方案1】:

一些建议:

  • ISNULL 检查会使查询变慢,尽量避免

  • 要显着提高速度,请为您过滤的列(如“IsSent”和“DateCreated”)以及分组依据的列创建索引。 还要在其 id 列上使用聚集索引为每个表建立索引。 https://docs.microsoft.com/en-us/sql/relational-databases/indexes/clustered-and-nonclustered-indexes-described?view=sql-server-ver15

  • 如果可能的话,尽量避免在同一张表上进行两次左连接。在您的情况下,我认为您可以将这些术语合并为一行

  • 最后——根据我的经验:有时执行 2 个查询要快得多: 假设您仅从 1 个大表中选择字段:首先只需选择第一个查询中的 ID。然后在第二个查询中选择所有字符串字段和过滤先前 ID 的其他计算。

祝你好运

【讨论】:

    猜你喜欢
    • 2018-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-07
    • 2021-06-21
    • 2015-11-18
    相关资源
    最近更新 更多