범위를 포함할 때 먼저 더 높은 카디널리티 열로 인덱싱
다음 표를 고려하세요.
CREATE TABLE `files` ( `did` int(10) unsigned NOT NULL DEFAULT '0', `filename` varbinary(200) NOT NULL, `ext` varbinary(5) DEFAULT NULL, `fsize` double DEFAULT NULL, `filetime` datetime DEFAULT NULL, PRIMARY KEY (`did`,`filename`), KEY `fe` (`filetime`,`ext`), -- This? KEY `ef` (`ext`,`filetime`) -- or This? ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
백만 개의 행과 파일 시간에 대한 높은 카디널리티 및 ext에 대한 낮은 카디널리티, 질문 fe 또는 ef 중 어느 인덱스가 더 유리한지에 대한 문제가 발생합니다.
Force Index 및 EXPLAIN을 사용한 분석
FORCE INDEX를 사용하여 두 인덱스를 테스트하면 성능에 분명한 차이가 있음을 알 수 있습니다. :
-- Forcing the range on filetime first mysql> EXPLAIN SELECT COUNT(*), AVG(fsize) FROM files FORCE INDEX(fe) WHERE ext = 'gif' AND filetime >= '2015-01-01' AND filetime < '2015-01-01' + INTERVAL 1 MONTH;
-- Forcing the low-cardinality ext first mysql> EXPLAIN SELECT COUNT(*), AVG(fsize) FROM files FORCE INDEX(ef) WHERE ext = 'gif' AND filetime >= '2015-01-01' AND filetime < '2015-01-01' + INTERVAL 1 MONTH;
EXPLAIN 출력은 ef가 훨씬 더 빠르다는 것을 나타냅니다. 더 적은 행을 사용하여 결과를 검색합니다.
Optimizer Trace를 사용한 분석
Optimizer 추적은 ef의 우수성을 확인합니다.
"potential_range_indices": [ ... { "index": "fe", "usable": true, ... }, { "index": "ef", "usable": true, ... } ], "analyzing_range_alternatives": { "range_scan_alternatives": [ { "index": "fe", "ranges": [ "2015-01-01 00:00:00 <= filetime < 2015-02-01 00:00:00" ], "cost": 20022, -- Higher cost }, { "index": "ef", "ranges": [ "gif <= ext <= gif AND 2015-01-01 00:00:00 <= filetime < 2015-02-01 00:00:00" ], "cost": 646.61, -- Lower cost } ], }
추적을 통해 ef가 인덱스의 두 열을 모두 사용할 수 있으므로 검색이 더 효율적이라는 것을 알 수 있습니다. 또한 Optimizer는 첫 번째 '범위' 열만 검사하므로 ext의 카디널리티는 관련이 없다는 점을 강조합니다.
결론
분석에 따르면, 여러 개의 인덱스 열이 포함된 범위 쿼리를 처리할 때 열의 순서는 다음과 같습니다. be:
이 접근 방식을 사용하면 인덱스가 가장 효과적으로 사용되어 최적의 쿼리 성능을 얻을 수 있습니다.
위 내용은 범위 쿼리가 있는 다중 열 인덱스에서 더 높은 카디널리티 열이 먼저 와야 합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!