database.sarang.net
UserID
Passwd
Database
DBMS
ㆍMySQL
PostgreSQL
Firebird
Oracle
Informix
Sybase
MS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
MySQL Q&A 30214 게시물 읽기
No. 30214
index관련 질문입니다.
작성자
지종현(whdgus15)
작성일
2012-02-22 21:19ⓒ
2012-02-22 21:24ⓜ
조회수
8,927

안녕하세요. index관련해서 테스트를 하던중에 궁금한점이 있어서 질문드립니다.

현재 사용하는 Mysql 버전은 5.1.41-3 을 사용하고 있고요.\

 

상황 : index가 걸려있는 컬럼을 select 할 경우 index를 타는데, index가 걸려있는 않은 컬럼도 select 를 할 경우 index를 타지 않습니다.(테이블은 MyISAM 입니다.)

 

ex) time컬럼이 index인 경우,

 

 select time from TB_TEST where time between 1329814800 and 1329832800;

=> ( index 사용 )

 

 select time, count from TB_TEST where time between 1329814800 and 1329832800;

=> ( index 사용안됨 )

 

 mysql> explain select time from TB_TEST where time between 1329829200 and 1329832800;
+----+-------------+-------------------------------+-------+---------------+------------+---------+------+-------+--------------------------+
| id | select_type | table                         | type  | possible_keys | key        | key_len | ref  | rows  | Extra                    |
+----+-------------+-------------------------------+-------+---------------+------------+---------+------+-------+--------------------------+
|  1 | SIMPLE      | TB_TEST | range | index_time    | index_time | 4       | NULL | 47782 | Using where; Using index |
+----+-------------+-------------------------------+-------+---------------+------------+---------+------+-------+--------------------------+
1 row in set (0.00 sec)

 

mysql> explain select time, idx from TB_TEST where time between 1329829200 and 1329832800;
+----+-------------+-------------------------------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table                         | type | possible_keys | key  | key_len | ref  | rows   | Extra       |
+----+-------------+-------------------------------+------+---------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | TB_TEST | ALL  | index_time    | NULL | NULL    | NULL | 103442 | Using where |
+----+-------------+-------------------------------+------+---------------+------+---------+------+--------+-------------+
1 row in set (0.00 sec)
 

왜 select에서 구해오는 값에 index가 걸려있는 컬럼만 있을경우 index를 타는데, index가 걸려있지 않은 컬럼까지 포함하면 index를 타지 않는 걸까요.... between 때문인건가요?ㅠㅠ;

이 글에 대한 댓글이 총 4건 있습니다.

참고로 between말고 부등호로 'time <= 시간 and time >= 시간' 으로 사용해도 마찬가지로 나오네요...

지종현(whdgus15)님이 2012-02-22 21:28에 작성한 댓글입니다.

 1줄 요점: 찾아봐야 되는 데이터의 범위가 너무 넓어서요.

 

time만 골라오는 경우에는 index만 뒤져서 처리가 가능합니다. 이를 일컬어 covered query라고 부르고 이때 사용되는 index를 covering index라고 부릅니다.

그런데 count까지도 가져오기 위해서는 index에 count 정보가 없기 때문에 index말고 table까지도 접근해서 data를 퍼 올려야 하는 상황에 처하게 됩니다.

전체 십만여건의 data를 대상으로 주어진 범위에 해당하는 데이타 건수를 4만7천여개가 해당할 것으로 통계를 근거로 예측을 하였습니다.

그렇다면 47천번 "index보고 table 쫒아가고"를 반복해서 수행하느니(index와 table을 보는 횟수를 모두 더하면 94천여번)

걍 인덱스를 포기하고 테이블을 다 퍼올려서 where조건에 해당하는 놈들만 filtering하지 머.. 그래봐야 십만건 차례대로 쳐다보면 되는데 94천번 왔다갔다 하는 것보단 효율이 좋겠군....이라고 옵티마이저가 판단했을 겁니다.

 

between으로 조회하는 범위를 전체 데이터의 반절에 해당하는 현재의 수준에서 확 줄인 범위를 where 조건으로 주면 '에이.. 그렇다면 index와 table을 왔다갔다 하면서 쳐다봐도 전체를 다 쳐다보는 것보다는 낫겠구먼'이라고 판단하고 index를 사용하게 될겁니다.

 

 

참고로 between 이나 부등호나 사람이 눈으로 보이는 것의 차이일 뿐 실제 처리는 100% 동일합니다.

우욱님이 2012-02-22 22:28에 작성한 댓글입니다. Edit

아... 그렇군요...

 

속도 고려를 해야하는데 참 애매하네요...ㅠㅠ

 

모든 컬럼에 인덱스를 줄 수도 없고... 저러면 인덱스를 안주는게 나은것같기도 하고;;

 

답변 정말 감사합니다^^ 많은 도움이 되었습니다.

지종현(whdgus15)님이 2012-02-23 10:20에 작성한 댓글입니다.

 로그성 데이타를 쌓기만 하고 지우거나 업데이트하지 않으신다면 ARCHIVE 엔진도 고려해보세요.

http://dev.mysql.com/doc/refman/5.1/en/archive-storage-engine.html

박현우(lqez)님이 2012-02-24 11:03에 작성한 댓글입니다.
[Top]
No.
제목
작성자
작성일
조회
30217mysql 원격접속에 문제가 있네요ㅠ [1]
안혜진
2012-03-01
8253
30216쿼리문 질문입니다. [1]
이정희
2012-02-28
7260
30215테이블 조인시 all로 묶이는 문제 [1]
최진규
2012-02-23
7661
30214index관련 질문입니다. [4]
지종현
2012-02-22
8927
30213무식한질문-중복값지우기 [1]
김길동
2012-02-21
7972
30212mysql 툴로 접속하려고 하는데 [2]
으악
2012-02-21
14101
30211난해한 쿼리 [1]
chqhcn
2012-02-21
8002
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2023 DSN, All rights reserved.
작업시간: 0.050초, 이곳 서비스는
	PostgreSQL v16.1로 자료를 관리합니다