2014-10-13 2 views
0

저는 약 18.7 백만 행이 있고 매월 약 50 만에서 100,000 행이있는 리포지토리 테이블이 있습니다. 테이블 구조는 다음과 같습니다.VARBINARY를 VARCHAR로, charindex를 VARCHAR로 변환하기위한 쿼리 최적화

CREATE TABLE [dbo].[my_table](
    [id] [bigint] NULL, 
    [a_timestamp] [datetime] NULL, 
    [eventId] [bigint] NULL, 
    [userId] [varchar](255) NULL, 
    [customerid] [varchar](128) NULL, 
    [messageType] [varchar](100) NULL, 
    [message] [varbinary](max) NULL 
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] 

나는 매월 다양한 카운트를 얻기 위해 다음 쿼리를 작성했습니다. 쿼리 실행에 약 10 분이 소요됩니다. 이 쿼리를 최적화하고 가능한 경우 몇 분 정도 시간을 가져올 수 있도록 도움이 필요합니다.

SELECT DATEADD(month, DATEDIFF(month, 0,a_timestamp), 0) AS MonthYear, 
     COUNT(*) AS [Count], 
     COUNT(DISTINCT customerid) AS [Unique Customers], 
     COUNT(DISTINCT userId) AS [Unique Users] 
FROM [my_table] 
WHERE messageType = 'Outbound' 
AND userId NOT IN ('master', 'admin') 
AND CHARINDEX('Retrieve Document',CONVERT(VARCHAR(MAX),[message])) > 1 
GROUP BY DATEADD(month, DATEDIFF(month, 0,a_timestamp), 0) 
ORDER BY MonthYear 

나는
  • CHARINDEX('Retrieve Document',CONVERT(VARCHAR(MAX),[message])) > 1

    은 VARCHAR로 VARBINARY에서 변환하여 사용자 이외의
  • userId NOT IN ('master', 'admin') 필터링 사용자의 문서 검색 '을하면 검색 다음과 같이 긴 실행 시간에 대한 주요 이유는 생각 목록 (실제 목록은 10 문자열 주위에 2 개의 문자열보다 길다)
  • 테이블의 1870 만 행

내가이 쿼리를 사용할 필요가 내가 SHOWPLAN 허가

  • 이없는 점 몇 내가이 테이블을 작성하지 않는

    • 주의하고 나는 그것을
    • 을 변경할 수 없습니다 Excel 데이터 연결 및 사용자가 Excel에서 실행하도록합니다. 사용자는 선택 권한 만 가질 수 있습니다.
  • 답변

    1

    기존 테이블을 변경할 수 없다면 전략을 변경하는 것이 좋습니다. 쿼리를 실행하고 매번 새로운 결과 집합을 작성하는 대신. 매월 새로운 결과를 다른 테이블에 삽입하지 마십시오 (AccumulatedResults라고 함).

    그런 식으로 매번 500K 개의 새 레코딩 만 처리합니다. 이것은 매번 전체 결과 세트를 재구성하는 것보다 훨씬 빠릅니다. 검색어는 다음과 같이 표시됩니다.

    INSERT INTO AccumulatedResults 
    (
        MonthYear, 
        [COUNT], 
        UniqueCustomers, 
        UniqueUsers, 
    ) 
    SELECT 
        DATEADD(month, DATEDIFF(month, 0, a_timestamp), 0) AS MonthYear, 
        COUNT(*) AS [Count], 
        COUNT(DISTINCT customerid) AS [Unique Customers], 
        COUNT(DISTINCT userId) AS [Unique Users] 
    FROM 
        [my_table] 
    WHERE 
        messageType = 'Outbound' AND 
        userId NOT IN ('master', 'admin') AND 
        CHARINDEX('Retrieve Document', CONVERT(VARCHAR(MAX), [message])) > 1 
    
        -- This is a new condition 
        AND DATEADD(month, DATEDIFF(month, 0, a_timestamp), 0) 
        > (SELECT MAX(MonthYear) FROM AccumulatedResults) 
    
    GROUP BY 
        DATEADD(month, DATEDIFF(month, 0, a_timestamp), 0) 
    
    +0

    +1 새 표 만들기에 대한 아이디어를 보내 주셔서 감사합니다. 엑셀 데이터 연결에서이 쿼리를 사용해야하고 사용자가 엑셀에서 실행하도록해야합니다. 사용자는 선택 권한 만 가질 수 있습니다. 그러므로 이것은 최선의 대답이 아닐 수도 있습니다. 이 질문을 반영하도록 수정합니다. – Ram

    +0

    내 솔루션을 사용하면 최종 사용자는 Excel 스프레드 시트에서 "AccumulatedResults"를 쿼리하여 거의 즉각적으로 쿼리 할 수 ​​있습니다. 위 쿼리는 한 달에 한 번만 실행하여 새 결과를 별도의 작업으로 삽입 할 수 있습니다. – JohnS

    +0

    별도의 직업은 방아쇠입니까? – Ram

    관련 문제