SQL 检测导致锁定/长查询的原因的策略

SQL Strategies for detecting what is causing a lock / long query

我有一个针对 Azure SQL 数据库的查询,偶尔会产生以下结果:

如果用户不多,就不会发生这种情况。但如果有,这种情况经常发生——查询需要很长时间才能完成,而且我的 DTU 百分比几乎超出了图表。

如何确定造成这种情况的原因?

一些一般信息:

代码:

 select USERID, USERNAME, NICKNAME, BIRTHDATE, LASTONLINE 
  from [User]  
  where AccountDisabled <> 1 and Banned <> 1 and 
     (ABOUTME <> '' OR ProvidedPhoto = 1) and 
     USERID <> @userId  and ProvidedPhoto = 1  AND 
     USERID IN (-1)  AND USERID NOT IN (-1)  
     AND USERID NOT IN (XXXX) UNION ALL  
          select * from (select USERID, USERNAME, NICKNAME, BIRTHDATE, LASTONLINE from [User] where 
                AccountDisabled <> 1 and 
                Banned <> 1 and (ABOUTME <> '' OR ProvidedPhoto = 1) and 
                USERID <> @userId  and ProvidedPhoto = 1  AND USERID NOT IN (-1)  
                AND USERID NOT IN (XXXX)  AND USERID NOT IN (-1)  
                order by LastOnline asc offset 0 rows fetch next + 20 rows only)          
     as dt

我对性能取证的世界有点陌生...任何建议都很棒。

更新 - 执行计划:

以下是您可以尝试的一些方法:

  1. 看看您是否可以通过将@UserID 作为参数传递来为return 您所需的列表创建一个存储过程。调用此存储过程而不是每次都生成查询。
  2. 将 NOT IN 替换为 NOT EXISTS,如下所示。首先检查这是否有帮助。这在很大程度上取决于 USERID 列中的值。

    SELECT USERID,USERNAME,NICKNAME,BIRTHDATE,LASTONLINE
    FROM [User]
    WHERE AccountDisabled <> 1
    AND Banned <> 1
    AND (
    ABOUTME <> ''
    OR ProvidedPhoto = 1
    )
    AND USERID <> @userId
    AND ProvidedPhoto = 1
    AND USERID IN (- 1)  --How will these two conditions ever be true together?
    AND USERID NOT IN (- 1) --Be sure about your conditions
    AND NOT EXISTS (SELECT USERID FROM [USER] U2 WHERE U1.USERID = U2.USERID)
    
    UNION ALL
    
    SELECT *
    FROM (  SELECT USERID,USERNAME,NICKNAME,BIRTHDATE,LASTONLINE
    FROM [User] U1
    WHERE AccountDisabled <> 1
    AND Banned <> 1
    AND (
        ABOUTME <> ''
        OR ProvidedPhoto = 1
        )
    AND USERID <> @userId
    AND ProvidedPhoto = 1
    AND USERID NOT IN (- 1)
    AND NOT EXISTS (SELECT USERID FROM [USER] U2 WHERE U1.USERID = U2.USERID)
    -- AND USERID NOT IN (- 1) WHY AGAIN??
    ORDER BY LastOnline ASC offset 0 rows FETCH NEXT + 20 rows ONLY
    ) AS dt
    
  3. 您可能还考虑在 WHERE 子句中的其他列上创建非聚集索引。您能否也显示查询的执行计划? (方法:在 SQL 查询编辑器中,按 CTRL+M,然后执行您的查询。您将获得一个执行计划以及结果。)