안녕하세요.
날짜와 관련된 속도 문의 드립니다.
northwind 데이터베이스에서 연습하고 있구요.
Orders테이블에 orderDate가 넌클러스터인덱스로 돼있고 타입은 datetime입니다.
예를들어 제가 2000년 5월 조건만 추출하고 싶다고 가정합니다.
첫번째 쿼리는 SARG를 모르고 orderDate에 연산을 넣었던 쿼리입니다.
SELECT * FROM orders WHERE datepart(yy, orderDate) = 1998 AND datepart(mm, orderDate) = 5
두번째 쿼리는 제 나름 SARG에 대해 공부했다 생각하고 작성한 쿼리입니다.
SELECT * FROM orders WHERE orderDate BETWEEN convert(datetime, '1998-05-01') AND convert(datetime, '1998-05-31')
(더 좋은 쿼리가 있다면 알려주세요.)
아래는 쿼리에 대한 결과입니다.
왜 첫번째 쿼리가 더 빠를까요??
convert(datetime, '날짜') 형식에서 과도한 연산이 발생하는걸까요?
아래는 논리적 읽기수인데 이건 두번째가 더 낮네요. 속도를 판별할때 어떤것이 기준이 되어야 하나요?
논리적읽기수, 쿼리비용, 예상IO비용, 예상CPU비용 어떤건가요?
첫번째 쿼리 읽기수
테이블 'Orders'. 검색 수 1, 논리적 읽기 수 33
두번째 쿼리 읽기수
테이블 'Orders'. 검색 수 1, 논리적 읽기 수 22
예상IO비용 비교
첫번째 : 0.0087
두번째 : 0.0170
Comment 3
-
진윤호
2013.04.09 09:32
-
카즈야마(이정우)
2013.04.09 10:15
안녕하세요.
질문 하신분 말씀이 1번안이 안좋은 쿼리라는걸 이미 알고 계신데
왜 1번이 성능상 더 좋냐라는 문의인거 같네요^^
-- 혹시 버퍼캐시 초기화하고 각각 테스트 하신건가요?
-
catchv
2013.04.09 18:22
예상IO를 보셔서 예상하시겠지만 두번째 쿼리가 훨씬 많은 페이지를 로드 합니다.
실제 페이지를 보면 1번은 Index Scan 하는데 4 page + Lookup 용 1 page를 불러 오면 되지만
밑에 쿼리의 경우는 22 page를 불러와야 데이터를 볼수 있는 구조 이므로
논리적 읽기 수는 1번이 많으나 밑에 것 보다는 상대적으로 적은 IO를 사용하게 되므로 성능이 좋게 나옵니다.
대체로 IO 적은 것이 가장 높은 성능(디스크가 제일 느리죠)을 볼 수 있지만 쿼리가 다 IO만 사용하는 것도 아니라서 종합적으로 보는 것이 좋을 것 같습니다.
-- catchv
WHERE datepart(yy, orderDate) = 1998 AND datepart(mm, orderDate) = 5
orderDate BETWEEN convert(datetime, '1998-05-01') AND convert(datetime, '1998-05-31')
두 구문을 비교 하게 되면 위에는 datetime 의 컬럼을 가공하고 있습니다.
컬럼을 가공하게 되면 index를 타지 않습니다.
따라서 속도의 차이가 예상됩니다.