SQL Server:从一个表运行两个左联接时,存储过程很慢

问题描述

我有一个存储过程,该查询运行一个查询获取行的数据,而不是从同一张表中有两个左联接的那张大表的行,但是执行起来很慢,每行最多6到20行需要300毫秒桌子。

如何优化此存储过程?

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检查会使查询变慢很多,请尽量避免

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

  • 尝试尽可能避免在同一张表上两次左联接。在您的情况下,我认为您可以将条款合并为一行

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

祝你好运