programing

SQL Server에서 날짜 시간 필터링의 성능을 향상시키는 방법은 무엇입니까?

starjava 2023. 10. 19. 21:48
반응형

SQL Server에서 날짜 시간 필터링의 성능을 향상시키는 방법은 무엇입니까?

필터링하는 데 문제가 있습니다.datetime기둥들

저는 이 두 가지 방법을 시도했습니다.

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

3,000,000개 이상의 주요 객체가 있는 대규모 데이터베이스를 가지고 있습니다.

그래서 성능을 향상시켜야 합니다.datetime여과의UNIX 타임스탬프(모두 변환)에 대해 읽고 있었습니다.datetimeUNIX 타임스탬프로 이동한 다음 이 UNIX 필드를 기준으로 필터링합니다.

내 생각엔 이게 더 나은 방법인 것 같아요datetime 다른 을 아는 하지만 다른 방법을 아시는 분이 있다면 감사하겠습니다.

제 질문은 다음과 같습니다.

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 타임스탬프는 어떨까요? 이것이 제가 질문을 던진 주된 이유입니다.필터링 성능을 향상시킬 수 있습니까?

msql의 날짜 시간 인덱스와 관련하여 제안하는 것은 인덱스 풋프린트가 검색 시간에 영향을 미치는 것입니다(예, 이는 명백한 것으로 보입니다...)앞으로 읽어주세요).

날짜 시간에 대한 색인을 작성할 때 중요한 사항은 '2015-06-05 22:47:20.102'와 같이 날짜 시간 내의 모든 위치를 색인이 설명해야 합니다.이것은 공간적으로 매우 크고 부피가 커집니다.새로운 날짜 시간 열을 만들고 시간을 시간으로 반올림한 다음 이 새 열을 기준으로 인덱스를 작성하여 데이터를 채우는 것이 성공적인 방법은 새 날짜 시간 열을 만들고 데이터를 채우는 것입니다.예 '2015-06-05 22:47:20.102'는 '2015-06-05 22:00:00.000'으로 번역됩니다.이 접근 방식을 사용하면 세부 데이터는 그대로 두고, 결과가 얼마나 빨리 반환되는지에 대해 약 10배(최소)의 수익률을 얻을 수 있는 이 새로운 열에서 이 데이터를 표시하거나 검색하여 사용할 수 있습니다.이는 인덱스가 분, 초 및 밀리초 필드를 설명할 필요가 없기 때문입니다.

SQL Server가 무엇을 하고 있는지 확인하려면 먼저 실행 계획을 살펴보아야 합니다.인덱스만 추가하면 될 것 같습니다.이와 같은 작은 변환이 쿼리가 느린 이유는 거의 없습니다.인덱스는 쿼리를 수정하는 데 좋은 첫 번째 단계입니다.

이 인덱스를 클러스터 인덱스로 만들 필요는 없습니다.클러스터 인덱스로 지정하면 조회를 수행할 필요가 없지만 100개의 행에 대해서만 조회 속도가 매우 빠릅니다.날짜 시간과 하위 범주를 비클러스터 인덱스에 순서대로 입력합니다.

주문하는 경우에는 인덱스에 있는지도 확인해야 합니다.테이블당 하나의 인덱스만 사용하는 것이 합리적이므로 모든 관련 열이 같은 인덱스, 올바른 순서로 나열되어 있는지 확인해야 합니다.

하지만 먼저 실제 실행 계획을 세우세요!

성능을 향상시키려면 다음과 같은 새 인덱스를 만들 것을 권장합니다.

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 조회 작업을 방지하고 쿼리의 전반적인 성능을 향상시킬 수 있습니다.

이거 먹어봐요.

;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
     )

datetime 필드에 클러스터 인덱스를 생성하면 도움이 될 것입니다. 우리는 앞서 같은 문제에 직면했습니다. datetime 열에 인덱스를 생성하여 해결했습니다.

언급URL : https://stackoverflow.com/questions/17381875/how-to-improve-performance-for-datetime-filtering-in-sql-server

반응형