날짜 검색을 2월 1일부터 15일까지 하면 인덱스가 잘 타는데요 2월 1일부터 3월 1일까지 하면 인덱스를 못탑니다.
원인이 어떤게 있을까요?? 데이터 필드들의 값을 확인 했구요..
흥미로운 문제네요.
테이블의 description과 해당 쿼리문을 올려주시면 함께 문제를 해결해보는데 도움이 될 듯 싶습니다.
안녕하세요 박성원입니다. 오호.. 먼가 궁금증을 확~ 불러 일으키는 문제인듯합니다. ^^;; 혹시 몰라서 좌변에 함수를 넣으면 안되는거지만 변환이라 이방법으로 했을때의 결과가 어떻게 되나요? explain SELECT * FROM `Test` WHERE from_unixtime(Time) between '2009-02-01' and '2009-02-15' 대략 반환값이 시간을 포함하게된다면 date_foramat을 또 써야하는데 그럼 더 이상해질듯해서요 ;; 일딴 상기퀴리로 한번 분석을 ^^;; ps.. unixtime때문에 예전에 많이 고생했었는데 지금보니 감회가 새롭네요 ㅋ
SELECT 'all' AS cntrange, COUNT(*) AS cnt FROM `Test` WHERE 1
UNION ALL
SELECT 'half Feb', COUNT(*) FROM `Test` WHERE 1 AND Time > UNIX_TIMESTAMP( '2009-02-01' ) AND Time < UNIX_TIMESTAMP( '2009-02-15' )
SELECT 'full Feb', COUNT(*) FROM `Test` WHERE 1 AND Time > UNIX_TIMESTAMP( '2009-02-01' ) AND Time < UNIX_TIMESTAMP( '2009-03-01' );
위 쿼리를 실행한 결과에 답이 들어있지 않을까 생각이 됩니다.
실행을 해보고 들여다 보지 않아서 짐작이지만
all과 full Feb는 거의 차이가 나지 않는 수치가 나오고
half Feb의 경우에는 all이나 full Feb보다는 비교적 적은 수치가 나온다면
DBMS는 주어진 쿼리를 수행함에 있어서
'3월 1일까지의 data를 가져오는 경우 뭐 이건 어차피 대부분의 data를 퍼 올리라는 얘기네 굳이 인덱스 갔다 데이터 갔다 왔다갔다 하다가 시간 다 잡아먹느니 그냥 몽창 퍼 올리고 필요없는걸 버리는 게 훨씬 쉽겠군'이라고 판단을 한 경우고,
'2월 15일까지만 가져오면 되는거지? 전체 다 읽어보는 것보단 당연히 색인을 보고 필요한 data만 쏙쏙 뽑아올리는게 더 빠르겠군'이라고 판단한 경우가 아닐까 싶습니다.
뭐 좀 더 알아보시려면 Cardinality, Density, Selectivity, index 등의 키워드로 검색을 해보시면 이해에 도움이 될만한 문서들을 찾아보실 수 있습니다.