2009-08-10 3 views
2

우선 순위가 매겨진 jBPM에 대해 mysql 인덱스를 최적화하는 것과 관련하여 another 질문이 있습니다. 관련 색인은 다음과 같습니다.왜 MySQL은 잘못된 색인을 사용합니까?

| JBPM_TIMER |   1 | JBPM_TIMER_REVERSEPRIORITY__DUEDATE_ |   1 | REVERSEPRIORITY_ | A   |   17 |  NULL | NULL | YES | BTREE  |   | 
    | JBPM_TIMER |   1 | JBPM_TIMER_REVERSEPRIORITY__DUEDATE_ |   2 | DUEDATE_   | A   |  971894 |  NULL | NULL | YES | BTREE  |   | 
    | JBPM_TIMER |   1 | JBPM_TIMER_DUEDATE_     |   1 | DUEDATE_   | A   |  971894 |  NULL | NULL | YES | BTREE  |   | 

JBPM은 타이머를 검색 할 때 두 가지 질문을합니다. 첫 번째 것은 결합 된 색인 (역순 우선 순위 및 양일간)과 솔로 듀 디이트 색인의 두 번째 색인에 따라 다릅니다. 솔로 인덱스를 추가 할 때이 쿼리를 실행하는 경우 그러나, 올바른보다 우선합니다 :

이 인덱스는 다른 쿼리에 필요한
mysql> explain select timer0_.ID_ as col_0_0_ from JBPM_TIMER timer0_ where timer0_.ISSUSPENDED_<>1 and timer0_.DUEDATE_<='2009-08-17 14:51:06' order by timer0_.REVERSEPRIORITY_ asc, timer0_.DUEDATE_ asc limit 160; 
+----+-------------+---------+-------+---------------------------+---------------------------+---------+------+-------+-----------------------------+ 
| id | select_type | table | type | possible_keys    | key      | key_len | ref | rows | Extra      | 
+----+-------------+---------+-------+---------------------------+---------------------------+---------+------+-------+-----------------------------+ 
| 1 | SIMPLE  | timer0_ | range | JBPM_TIMER_DUEDATE_  | JBPM_TIMER_DUEDATE_ERIK_T | 9  | NULL | 971894| Using where; Using filesort | 
+----+-------------+---------+-------+---------------------------+---------------------------+---------+------+-------+-----------------------------+ 
1 row in set (0.00 sec) 

:

mysql> explain select timer0_.ID_ as col_0_0_ from JBPM_TIMER timer0_ where (timer0_.EXCEPTION_ is null) and timer0_.ISSUSPENDED_<>1 order by timer0_.DUEDATE_ asc limit 160; 
+----+-------------+---------+-------+---------------+---------------------+---------+------+-------+-------------+ 
| id | select_type | table | type | possible_keys | key     | key_len | ref | rows | Extra  | 
+----+-------------+---------+-------+---------------+---------------------+---------+------+-------+-------------+ 
| 1 | SIMPLE  | timer0_ | index | NULL   | JBPM_TIMER_DUEDATE_ | 9  | NULL | 24249 | Using where | 
+----+-------------+---------+-------+---------------+---------------------+---------+------+-------+-------------+ 
1 row in set (0.00 sec) 

솔로 인덱스를 제거, 쿼리 수 (1) 올바르게 실행되고 쿼리 2에 filesort가 필요합니다. 솔로 인덱스 쿼리 번호 2를 올바르게 추가하면 쿼리 1에 filesort가 필요합니다.

explain select timer0_.ID_ as col_0_0_ 
from JBPM_TIMER timer0_ USE INDEX (JBPM_TIMER_REVERSEPRIORITY__DUEDATE_) 
where timer0_.ISSUSPENDED_<>1 and 
    timer0_.DUEDATE_<='2009-08-17 14:51:06' 
order by timer0_.REVERSEPRIORITY_ asc, timer0_.DUEDATE_ asc 
limit 160; 

이 힌트 MySQL이 제대로 두 쿼리를 최적화하기 위해 갈 수있는 유일한 방법입니다

이 원치 않는 행동

은 첫 번째 쿼리에 인덱스 힌트를 추가하여 오버라이드 (override) 할 수 있습니까? 아니면 우리가 뭔가 잘못하고 있는거야?

답변

3

(DUEDATE_, REVERSEPRIORITY_)에 색인을 추가하십시오. 그것은 여전히 ​​filesort (나는 생각한다)를 사용하지만 훨씬 적은 수의 행에있을 것이다.

또한 OPTIMIZE TABLE table_name 테이블을 사용하고 테이블을 CHECK TABLE table_name (따라서 mysql은 인덱스 값을 다시 계산합니다).

이것은 모두 교육받은 추측입니다.

+0

좋은 제안은 쿼리를 가속화하고 where 절이 작은 파일 세트를 신속하게 정렬 할 때 정상로드로 실제로 작동합니다. 다른 해결책에 대한 자세한 내용은 아래의 "답변"을 참조하십시오. – Erik

0

당신은 정확합니다, 우리는 심지어 다른 인덱스를 제거 할 수 있습니다 (duedate, reversepriority).

이것은 두 열을 정렬하는 쿼리의 경우 where 절에 의해 선택된 행을 MySQL 파일로 만드는 것으로 보입니다.

duedate 만 정렬하는 쿼리는 정렬 할 필요가 없습니다.

mysql> explain select timer0_.ID_ as col_0_0_ from JBPM_TIMER timer0_ where timer0_.ISSUSPENDED_<>1 and timer0_.DUEDATE_<='2009-08-17 14:51:06' order by timer0_.REVERSEPRIORITY_ asc, timer0_.DUEDATE_ asc limit 160; 

과 같은 where 절에 REVERSEPRIORITY_ 열을 추가 :

mysql> explain select timer0_.ID_ as col_0_0_ from JBPM_TIMER timer0_ where timer0_.ISSUSPENDED_<>1 and timer0_.DUEDATE_<='2009-08-17 14:51:06' and timer0_.REVERSEPRIORITY < 0 order by timer0_.REVERSEPRIORITY_ asc, timer0_.DUEDATE_ asc limit 160; 

를 MySQL은 올바른 (결합) 인덱스를 사용하게

그러나, 우리는 쿼리를 수정하는 것을 발견했다.

+1

입력 해 주셔서 감사합니다. 참고 : 최적화 도구를 사용하려고합니다. 지금은 효과가 있지만 예상대로 작동하지는 않습니다. 만약 당신이 더 잘 알고 있다면 인공 지형을 추가하는 대신 힌트를 사용해야합니다. –

+0

예, 우리가하는 일에 동의합니다. 우리가 SQL을 소개해야한다는 힌트와 함께 HQL을 사용할 수 있습니다. 나는 고위 개발자에게 결정을 맡길 것이다. :) – Erik

관련 문제