SQL Strategies用于检测导致锁定/长查询的原因

时间:2016-05-10 03:37:48

标签: sql performance entity-framework database-performance dapper

我对Azure SQL数据库进行了查询,偶尔会导致以下结果:

enter image description here

如果没有很多用户,这不会发生。但如果有,这种情况经常发生 - 查询需要很长时间才能完成,我的DTU百分比几乎不在图表之外。

如何确定导致此问题的原因?

一些一般信息:

  • 我在应用程序的某些部分使用dapper作为ORM
  • 我在其他地区使用EF
  • 当它挂起时,它会挂起> 30秒。很少是1s <1。时间&lt; 30秒
  • 挂起的dapper查询位于下方,其中XXXX是两种情况下约2,500个商品ID的列表:
  • 似乎有一小部分XXXX Ids的用户不会遇到此问题。 XXXX的检索不是问题 - 但使用大XXXX似乎有时会加剧性能。
  • [User]在UserId(PK)和LastOnline
  • 上编制索引

代码:

 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

我对性能取证的世界有点新意见......任何建议都会很棒。

更新 - 执行计划:

enter image description here

1 个答案:

答案 0 :(得分:2)

以下是您可以尝试的一些事项:

  1. 通过传递@UserID作为参数,查看是否可以创建存储过程以返回所需的列表。调用此存储过程,而不是每次都生成查询。
  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然后执行查询。您将获得执行计划以及结果。)