2010-12-03 5 views
0

나는 내가 할 경우 (k1,k2,k3)
에 인덱스 m_idx
SELECT c1,c2,c3... FROM tb FORCE INDEX (m_idx) WHERE k1=500 AND k2 IN(...) AND k2>2000 ORDER BY k1 LIMIT 1000;
또는
SELECT c1,c2,c3... FROM tb FORCE INDEX (m_idx) WHERE k1 IN (500,1000,1500 ...) AND k2 IN(...) AND k2>2000 ORDER BY k1 LIMIT 1000;
Handler_read_next = 999가장 왼쪽의 다중 색인에서 범위로 선택할 수 있습니까?

하지만 K1에 범위를 사용하려고하면 :
SELECT c1,c2,c3... FROM tb FORCE INDEX (m_idx) WHERE k1>=500 AND k2 IN(...) AND k2>2000 ORDER BY k1 LIMIT 1000;
Handler_read_next = 58035
모든 경우에 EXPLAIN은 사용 된 키가 m_idx 0123임을 나타냅니다. 하지만 제 생각에는 m_idx이 사용되지 않았습니다 (또한 k1에만 색인이 있음).
그렇지 않으면 왜 1000 행 이상을 읽는 지 이해할 수 없습니다.
인덱스에서 m_idx 인덱스를 검색하고 테이블에서 읽을 조건을 충족하는 행 ONLY the first 1000을 검색하려고합니다.
사실 제 3의 경우 인덱스를 스캔하고 tb1에서 k1 조건을 충족하는 행을 읽은 다음 tb에서 k2 및 k3 조건을 확인합니다.
나는 다음을 사용한다 : MyISAM, WINDOWS 7 64와 함께 MySql, tb는 1 mil 행을 가진다;
내 질문은 :
가장 왼쪽의 다중 색인에서 범위별로 선택할 수 있습니까?
또는
다른 문제가 있습니까?
감사합니다.

답변

0
  1. 아니요.
  2. 아니, 당신은 그래서 당신이 수행하는 최적화 도움이되지 수있는 모든 권리

http://dev.mysql.com/doc/refman/5.1/en/range-optimization.html ("다중 파트 인덱스에 대한 7.3.1.3.2. 레인지 액세스 방법"부분)

을하고있는 쿼리가 빠릅니다.

옵티마이 저가 어떤 색인을 사용할 지 더 잘 알고 있으므로 FORCE INDEX을 사용하지 마십시오.

또한

:

k1>=500 AND k2 IN(...) AND k2>2000 

이 부분은 적은 레코드를 반환있는 따라 중 하나 k1>=500 또는 k2 IN(...) AND k2>2000는 (나는 당신이 전에 IN()에 추가 수동으로 비교할 수 있습니다 때문에 당신이 여기 > 2000 필요 왜 확실하지 않다), 인덱스 k2을 만들 수도 있습니다 ( k2 부분이 적은 양의 레코드를 반환하는 경우).

+0

나는 이미이 장을 읽었으며 나는 그것이 가능하지 않다는 것을 명백하게 말할 수 없다는 것을 발견하지 못했다. "BTREE 인덱스의 경우, AND와 결합 된 조건에 대해 간격을 사용할 수 있습니다. ** 각 조건 **은 =, <=>, IS NULL 등을 사용하여 키 부분을 상수 값과 비교합니다. >, <, > =, <=, !=, <>, BETWEEN 또는 LIKE'라고 표시됩니다. ** 각 조건은 **입니다. – silversky

+0

@silversky : 예, ** **일지도 모르지만 귀하의 경우는 아닙니다 (모든 경우가 아님). 기술적으로 가능합니다. 그런 종류의 쿼리에는 적합하지 않습니다."조건과 일치하는 모든 행을 포함하는 단일 키 튜플을 결정할 수있는 한 간격을 사용할 수 있습니다"- 이것은 핵심 구입니다. 이 구절 바로 뒤의 샘플을 보아라. 그것은 당신 것과 완전히 같다. – zerkms

+0

@zerkms 나는이 문서가 때때로 아주 나쁘다 고 말하면 내가 틀렸다고 생각하지 않는다. 이 장의 첫 번째 단락에서, '다중 부분 색인의 범위 조건은 색인 행이 하나 또는 여러 개의 키 튜플 간격 내에 있도록 제한합니다.'그리고 나중에 (여러분이 지적한 것처럼) key tuple' – silversky