>source

Sites 및 ScannedItems 테이블이 두 개 있습니다. Sites에는 약 15000 개의 행이 있고 ScannedItems에는 약 6 천만 개의 행이 있습니다. 아래 쿼리는 CountUniqueRoleAssignments, Modified 및 siteid의 인덱스를 사용하여 약 6 분이 걸립니다. 어떤 식 으로든 최적화 할 수 있습니까? 어떤 종류의 조인이 하위 쿼리 또는 다른 힌트보다 빠릅니까?

select 
    *,
    (select COUNT(*) from ScannedItems where ScannedItems.siteid=sites.siteid and ScannedItems.CountUniqueRoleAssignments>0) as CountUniquePermissions,
    (select COUNT(*) from ScannedItems where ScannedItems.siteid=sites.siteid and ScannedItems.Modified<DATEADD (day, -30 ,GETDATE())) as CountNotModified30Days
from sites


  • 답변 # 1

    아마도 조인을 사용하여이 쿼리를 작성할 것입니다.

    SELECT
        s.siteid,
        COALESCE(si.CountUniquePermissions, 0) AS CountUniquePermissions,
        COALESCE(si.CountNotModified30Days, 0) AS CountNotModified30Days
    FROM sites s
    LEFT JOIN
    (
        SELECT siteid,
               COUNT(CASE WHEN CountUniqueRoleAssignments > 0 THEN 1 END)
                   AS CountUniquePermissions,
               COUNT(CASE WHEN Modified < DATEADD (day, -30, GETDATE()) THEN 1 END)
                   AS CountNotModified30Days
        FROM ScannedItems
        GROUP BY siteid
    ) si
        ON si.siteid = s.siteid
    ORDER BY
        s.siteid;
    
    

    위의 쿼리에는 WHERE 또는 HAVING 그래서 나는 인덱스를 사용하여 그것을 더 조정하는 명백한 방법을 보지 못했습니다. 그러나 적어도 현재 쿼리와 관련되지 않은 잠재적 이점이 있습니다. N^2 select 절에서 상호 관련된 하위 쿼리와의 동작.

  • 답변 # 2

    당신은 사용할 수 있습니다 LEFT JOIN 다음과 같이 조건부 집계 :

    select 
        S.siteid,
        COUNT(CASE WHEN SI.CountUniqueRoleAssignments > 0 THEN 1 END) as CountUniquePermissions,
        COUNT(CASE WHEN SI.Modified<DATEADD (day, -30 ,GETDATE()) THEN 1 END ) as CountNotModified30Days
    from sites S
    LEFT JOIN ScannedItems SI ON SI.siteid = S.siteid
    GROUP BY S.SITEID
    
    

  • 이전 javascript - 오류가 표시 될 때 "삽입"버튼을 비활성화 할 수있는 방법이 있습니까?
  • 다음 rdoc - JRuby에서 ri 문서를 어떻게 설치합니까?