2009-07-17 3 views
7

나는 3 개의 컬럼을 기반으로하는 복합 인덱스를 가지고 있는데, 두 개는 내 쿼리에 제약이 있고 세 번째 것은 order by 절이다. 아직 mysql은 인덱스를 정렬에 사용하지 않는다.정렬을 위해 인덱스를 사용하기 위해 mysql 쿼리를 최적화한다.

 
explain select * from videos where public_private='public' and approved='yes' order by number_of_views desc; 

+----+-------------+--------+------+--------------------------------+------+---------+------+---------+-----------------------------+ 
| id | select_type | table | type | possible_keys     | key | key_len | ref | rows | Extra  | 
+----+-------------+--------+------+--------------------------------+------+---------+------+---------+-----------------------------+ 
| 1 | SIMPLE  | videos | ALL | approved,approved_3,approved_2 | NULL | NULL | NULL | 1476818 | Using where; Using filesort | 
+----+-------------+--------+------+--------------------------------+------+---------+------+---------+-----------------------------+ 

테이블 구조는 다음과 같습니다

CREATE TABLE `videos` (
    `indexer` int(9) NOT NULL auto_increment, 
    `user_id` int(9) default NULL, 
    `public_private` varchar(24) default NULL, 
    `approved` varchar(24) default NULL, 
    `number_of_views` int(9) default NULL, 
    PRIMARY KEY (`indexer`), 
    KEY `approved` (`approved`,`user_id`), 
    KEY `approved_3` (`approved`,`public_private`,`indexer`), 
    KEY `approved_2` (`approved`,`public_private`,`number_of_views`), 
) ENGINE=MyISAM AUTO_INCREMENT=1969091 DEFAULT CHARSET=utf8 | 

내가 결과를 정렬 인덱스를 사용하는 MySQL을 강제로해야합니까?

답변

13

을 수행하기 위해 3을 사용하는 경우에만 해당 키를 사용합니다 테이블의 데이터. 이와 같은 상황에서, MySQL 옵티마이 저는 종종 인덱스 스캔을 선택하고 인덱스를 완전히 무시합니다. 실제로 인덱스 전체를 읽는 문제를 겪고 데이터를 선택하는 것보다 빠릅니다. 이 경우, public_private='yes' and approved='yes'이 표의 상당 부분과 일치한다고 생각합니다. 따라서 MySQL이이 때문에 인덱스를 사용하지 않고 건너 뛴다면 정렬 할 수 없습니다. 당신이 정말로 그것을 인덱스를 사용하려면

것은, 그 해결책은 FORCE INDEX을 사용하는 것입니다 :

select * from videos FORCE INDEX (approved_2) where public_private='public' and approved='yes' order by number_of_views desc; 

그러나, 나는 당신이 얻고있는 것은 사실보다 더 빨리이 있는지 확인하려면 몇 가지 테스트를 실행하는 것입니다 MySQL 옵티마이 저가 선택했던 것. 분명히 옵티 마이저 does have some issues과 함께 주문을 선택 했으므로 성능을 향상시킬 수 있는지 확인할 수 있습니다.

+0

FORCE INDEX가 문제를 해결했습니다. 쿼리가 훨씬 빠르게 실행되고 데이터베이스의 많은 부분과 일치하는 쿼리에 대해 올바르게 수행됩니다. –

+0

좋은 물건, 다행. – zombat

-2

주문은 복합 키에서 중요합니다. 나는 규칙을 잊어 버렸지 만, 다른 순서로 시도하십시오.

-2

number_of_views 열에 별도의 색인을 추가하여 작동하는지 확인하십시오. 키가 3 개 컬럼의 조합 인 경우

, 당신이 가지고있는 쿼리 아마의 큰 비율을 일치하고 있다고 생각 작업을

+0

올바른 번호 : 키가 3 열의 조합 인 경우 첫 번째 열 또는 첫 번째 두 열의 조합 또는 세 열 모두를 사용할 때 특정 키를 사용합니다. –

1

주문은 복합 키에서 중요합니다. 당신은 단지 number_of_viewsapproved_2 키 변경을 사용하여 정렬 할 경우

KEY `approved_2` (`approved`,`public_private`,`number_of_views`) 

에 : 왼쪽에서 오른쪽으로 MySQL의 일에

KEY `approved_2` (`number_of_views`,`approved`,`public_private`) 

복합 키. 위의 예에서, 키, number_of_viewsapproved를 사용하여 선언하고, public_private implicity은에 인덱스를 생성합니다

  • number_of_views
  • number_of_views, approved
  • number_of_views, approved, public_private
+0

이 솔루션은 첫 번째 두 필드를 필터링하고 세 번째 필드를 정렬 할 수있는 가능성을 'MySQL'에서 박탈합니다. – Quassnoi

+0

그는 색인이 정렬에 사용되지 않은 이유를 묻습니다. –

+1

제안하는 색인은 정렬에만 사용할 수 있습니다. '@ op '에 의해 제안 된 인덱스는 정렬을 위해 *와 *를 필터링하는데 사용될 수 있습니다. 색인은 필터링에 사용할 수 없지만 정렬에 사용될 수도 있고 그렇지 않을 수도 있습니다. – Quassnoi

0

이 작동합니다 :

`select * from videos where approved='yes' and public_private='public' order by number_of_views desc;` 

아니요. number_of_views에 별도의 색인을 만드십시오.

이것은 작동해야합니다.

(MySQL은이 순서대로 사용하지 않을 경우 그래서 approved에 색인이 public_private는, number_of_views가. 즉, 당신은 왼쪽에서 왼쪽 세, 2 또는 가장 왼쪽 하나를 사용할 수 있습니다 작동하지 않습니다. 기본적으로 왼쪽에서 오른쪽으로 순서를 다음과 하지만 가장 왼쪽의 것을 사용하지 않으면 작동하지 않습니다.)

별도의 인덱스를 사용하면 number_of_views이 자동으로 정렬되므로 order by에 도움이 될 수 있습니다.

+0

인덱스 'number_of_views'만 추가하면 'where'조건을 만족하는 인덱스가 고려되므로 문제를 해결할 수 없습니다. OP의 답변에서'approved_2' 인덱스가 사용되어야하고'approved, public_private' 및'number_of_views'에 별도로 인덱스되지 않아야합니다. –

관련 문제