복붙노트

[SQL] 어떻게 SQL 서버에서 날짜 필터링의 성능을 향상시키기 위해?

SQL

어떻게 SQL 서버에서 날짜 필터링의 성능을 향상시키기 위해?

나는 날짜 열을 기준으로 필터링에 문제가 있습니다.

나는이 두 가지 방법을 시도 :

datefield < '2013-03-15 17:17:55.179'
datefield < CAST('2013-03-15 17:17:55.179' AS datetime)

나는 이상 3.000.000 주요 목적이있는 대형 데이터베이스를 가지고있다.

그래서 난 내 날짜 필터링 성능을 개선 할 필요가있다. 나는 UNIX 타임 스탬프 (이 UNIX 필드가 UNIX 타임 스탬프 다음 필터에 대한 모든 날짜 변환)에 대해 읽고 있었다.

나는 날짜에 의해 필터링보다 더 좋은 방법 같아요. 누구든지 다른 방법을 알고 있다면, 나는 그것을 감사하겠습니다.

내 질문은 :

SELECT TOP (100)  ev.Title as Event_name, po.Name as POI_name, 
po.Address, po.City, po.Region, po.Country, po.Latitude, po.Longitude, ev.Start_time, 
(Select ID_Category FROM SubCategory s where ev.ID_SubCategory = s.ID_SubCategory) as ID_Category, 
ev.ID_SubCategory, ev.ID_Event, ev.ID_Channel, IDChanelEvent, 
ev.FavoriteCount, po.gmtOffset, v.IsFavorite, v1.IsFavorite  
FROM Events ev 
JOIN POI po ON ev.ID_POI = po.ID_POI 
JOIN (SELECT et.id_event as joinIdEv FROM EventTagLink et, tags t 
 WHERE t.id_tag = et.id_tag 
 AND ( t.Title = N'music' ) 
 ) as joinEvents 
 ON joinEvents.joinIdEv = ev.ID_Event 
LEFT JOIN Viewed v ON v.ID_Event = ev.ID_Event AND v.ID_User = 1 AND v.IsFavorite = 1 LEFT join Viewed v1 ON v1.ID_Event = ev.ID_Event AND v1.ID_User = 1 AND v1.IsFavorite = 0
WHERE 
--ev.GmtStop_time > '2013-03-15 14:17:55.188' AND 
po.Latitude > 41.31423 AND po.Latitude < 61.60511 
AND  po.Longitude > -6.676602 AND po.Longitude < 17.04498  
AND ev.ID_SubCategory in (3, 12, 21, 4, 30, 13, 22, 6, 14, 40, 23, 7, 32, 15, 41, 8, 50, 33, 16, 42, 25, 9, 34, 17, 35, 18, 44, 27, 36, 19, 45, 28, 37, 46, 29, 38, 47, 39, 48, 49, 10, 1, 11, 2, 20) 
--AND ev.GmtStart_time< '2013-03-15 17:17:55.179'
AND v1.IsFavorite is null

내가 댓글을 달았습니다 시간에 의해 필터링.

나는이 필터를 해제하면, 요청 지속 시간은 몇 초입니다. 그때 요청 시간에 그들을 설정하면 25초 이상이다.

그래서 등등 계획, 인덱스 및 실행에 대한 많은 논의가있다. 하지만 제가이 질문을 넣어 한 주요 이유입니다 UNIX 타임 스탬프에 대한. 이 날짜 필터링 성능을 향상시겠습니까?

미리 감사드립니다.

해결법

  1. ==============================

    1.이 SQL에서 날짜의 인덱스에 관해서 그냥 제안에 미치는 영향이 번 검색 인덱스 풋 프린트 (예 이것은 분명한 것 같다 ...하지만 이후 읽어 보시기 바랍니다)입니다.

    이 SQL에서 날짜의 인덱스에 관해서 그냥 제안에 미치는 영향이 번 검색 인덱스 풋 프린트 (예 이것은 분명한 것 같다 ...하지만 이후 읽어 보시기 바랍니다)입니다.

    예를 들어 날짜 시간 말에 색인이에 importances '2015년 6월 5일 22 : 47 : 20.102'인덱스는 날짜 내의 모든 장소를 계정에 있습니다. 이것은 매우 큰 공간 부피된다. 내가 활용 한 것이 성공적인 접근 방식은 새로운 날짜 열을 생성하고이 새로운 컬럼에 인덱스를 구축 한 후 시간에 시간을 반올림에 의해 데이터를 채우는 것입니다. 예 '2015년 6월 5일 22 : 47 : 20.102은': 00 : 00.000 2015년 6월 5일 (22 ')로 변환한다. 이 방법을 취함으로써 우리는 혼자 자세한 데이터를 남겨두고을 표시하거나 우리에게 반환하는 방법을 빠른 결과에 약 10 배 (최소) 수익을주는이 새로운 열을 검색하여 사용할 수 있습니다. 이는 인덱스는 분, 초 및 밀리 초 필드에 계정이없는 사실이다.

  2. ==============================

    2.먼저 SQL Server가 무엇을하고 있는지 확인하기 위해 실행 계획을보고해야합니다. 더 많은 것보다는 아마, 당신은 단지 인덱스를 추가 할 필요가있다. 이 같은 리틀 전환은 거의 쿼리가 느린 이유 적이 없습니다. 지수는 쿼리를 고정하기위한 좋은 첫 정지합니다.

    먼저 SQL Server가 무엇을하고 있는지 확인하기 위해 실행 계획을보고해야합니다. 더 많은 것보다는 아마, 당신은 단지 인덱스를 추가 할 필요가있다. 이 같은 리틀 전환은 거의 쿼리가 느린 이유 적이 없습니다. 지수는 쿼리를 고정하기위한 좋은 첫 정지합니다.

    이 클러스터 된 인덱스를 만들 필요가 없습니다. 그것에게 당신이 조회를 수행 할 필요가 없습니다, 그러나 단지 100 행에 대해, 조회가 매우 빠른 것으로 클러스터 된 인덱스 수단을 만들기. 그 순서, 클러스터되지 않은 인덱스에 날짜와 하위 범주를 둘 것입니다.

    당신이 주문하는 경우에는 인덱스에서 확인하십시오의해야합니다. 그것은 단지 테이블 당 하나의 인덱스를 사용하는 의미가 있기 때문에, 당신은 올바른 순서로, 반드시 모든 관련 열이 같은 인덱스에 확인해야합니다.

    하지만 먼저, 실제 실행 계획을 얻을!

  3. ==============================

    3.내가 제안 더 나은 성능을 위해 당신은 새로운 인덱스를 만들 :

    내가 제안 더 나은 성능을 위해 당신은 새로운 인덱스를 만들 :

    CREATE INDEX x1 ON LiveCity.dbo.Tags(Title) INCLUDE(ID_Tag)
    CREATE INDEX x2 ON LiveCity.dbo.Tags(ID_Event, GmtStart_time, GmtStop_time) 
      INCLUDE(
              FavoriteCount, 
              ID_Channel, 
              ID_POI, 
              ID_SubCategory, 
              IDChanelEvent, 
              Start_time, 
              Title
              )
    CREATE INDEX x ON LiveCity.dbo.POI(ID_POI, Latitude, Longitude) 
      INCLUDE(
              Address, 
              City, 
              Country, 
              gmtOffset, 
              Name, 
              Region
              )
    

    이것은 당신이 RID 조회 작업을 방지하고 쿼리의 전체적인 성능이 향상됩니다.

  4. ==============================

    4.이거 한번 해봐 -

    이거 한번 해봐 -

    ;WITH cte AS (
         SELECT IsFavorite, ID_Event  
         FROM Viewed
         WHERE ID_User = 1 
    )
    SELECT TOP (100)
          Event_name = ev.Title 
        , POI_name = po.Name 
        , po.[address]
        , po.City
        , po.Region
        , po.Country
        , po.Latitude
        , po.Longitude
        , ev.start_time
        , s.ID_Category
        , ev.ID_SubCategory
        , ev.ID_Event
        , ev.ID_Channel
        , IDChanelEvent
        , ev.FavoriteCount
        , po.gmtOffset
        , v.IsFavorite
        , IsFavorite = NULL
    FROM [events] ev
    JOIN POI po ON ev.ID_POI = po.ID_POI
    LEFT JOIN SubCategory s ON ev.ID_SubCategory = s.ID_SubCategory
    LEFT JOIN cte v ON v.ID_Event = ev.ID_Event AND v.IsFavorite = 1
    WHERE po.Latitude BETWEEN 41.31423 AND 61.60511
         AND po.Longitude BETWEEN -6.676602 AND 17.04498
         AND ev.ID_SubCategory IN (3, 12, 21, 4, 30, 13, 22, 6, 14, 40, 23, 7, 32, 15, 41, 8, 50, 33, 16, 42, 25, 9, 34, 17, 35, 18, 44, 27, 36, 19, 45, 28, 37, 46, 29, 38, 47, 39, 48, 49, 10, 1, 11, 2, 20)
         AND v1.IsFavorite IS NULL
         AND EXISTS(
              SELECT 1 
              FROM EventTagLink et
              WHERE t.Title = 'music'
                   AND et.joinIdEv = ev.ID_Event
         )
         AND NOT EXISTS (
              SELECT * 
              FROM cte v1 
              WHERE v1.ID_Event = ev.ID_Event AND v1.IsFavorite = 0
         )
    
  5. ==============================

    5.날짜 필드에 클러스터 인덱스를 작성하고 도움은 확실히. 우리는 이전에 같은 문제에 직면했다. 우리는 날짜 컬럼에 인덱스를 생성하여 그것을 해결.

    날짜 필드에 클러스터 인덱스를 작성하고 도움은 확실히. 우리는 이전에 같은 문제에 직면했다. 우리는 날짜 컬럼에 인덱스를 생성하여 그것을 해결.

  6. from https://stackoverflow.com/questions/17381875/how-to-improve-performance-for-datetime-filtering-in-sql-server by cc-by-sa and MIT license