2009-08-10 5 views
2

Nous avons un problème avec notre environnement de production qui utilise une version modifiée de jBPM qui prend en charge les priorités. Les indices actuels sont les suivants:Solution de contournement pour la fonction d'index descendant manquante dans MySQL

| JBPM_TIMER |   1 | JBPM_TIMER_DUEDATE__PRIORITY_ |   1 | PRIORITY_  | A   |   2 |  NULL | NULL | YES | BTREE  |   | 
| JBPM_TIMER |   1 | JBPM_TIMER_DUEDATE__PRIORITY_ |   2 | DUEDATE_   | A   |   51 |  NULL | NULL | YES | BTREE  |   | 

La requête problématique:

mysql> explain select * from JBPM_TIMER where PRIORITY_ < 0 order by PRIORITY_ ASC, DUEDATE_ desc; 
+----+-------------+------------+-------+-------------------------------+-------------------------------+---------+------+------+-----------------------------+ 
| id | select_type | table  | type | possible_keys     | key       | key_len | ref | rows | Extra      | 
+----+-------------+------------+-------+-------------------------------+-------------------------------+---------+------+------+-----------------------------+ 
| 1 | SIMPLE  | JBPM_TIMER | range | JBPM_TIMER_DUEDATE__PRIORITY_ | JBPM_TIMER_DUEDATE__PRIORITY_ | 5  | NULL | 10 | Using where; Using filesort | 
+----+-------------+------------+-------+-------------------------------+-------------------------------+---------+------+------+-----------------------------+ 
1 row in set (0.00 sec) 

La requête avec PRIORITY_ sorted ascendingSommaire à la place:

mysql> explain select * from JBPM_TIMER where PRIORITY_ < 0 order by PRIORITY_ ASC, DUEDATE_ asc; 
+----+-------------+------------+-------+-------------------------------+-------------------------------+---------+------+------+-------------+ 
| id | select_type | table  | type | possible_keys     | key       | key_len | ref | rows | Extra  | 
+----+-------------+------------+-------+-------------------------------+-------------------------------+---------+------+------+-------------+ 
| 1 | SIMPLE  | JBPM_TIMER | range | JBPM_TIMER_DUEDATE__PRIORITY_ | JBPM_TIMER_DUEDATE__PRIORITY_ | 5  | NULL | 10 | Using where | 
+----+-------------+------------+-------+-------------------------------+-------------------------------+---------+------+------+-------------+ 
1 row in set (0.00 sec) 

recherche sur Google suggère autour que la solution est d'ajouter une autre colonne (REVERSEPRIORITY_) qui contient la valeur de PRIORITY_ * -1 et indexe celle-ci à la place. Cela me semble être une solution plutôt moche, donc je veux vous demander si vous en avez de meilleurs!

+0

Question de suivi ici: http://stackoverflow.com/questions/1256568/why-does-mysql-use-the-wrong-index – Erik

Répondre

1

-PRIORITY est la meilleure solution.

Cependant, vous pouvez utiliser MySQLFORCE INDEX et STRAIGHT_JOIN à imiter SKIP SCAN:

SELECT jt * 
FROM (
     SELECT DISTINCT priority 
     FROM JBPM_TIMER 
     ORDER BY 
       priority DESC 
     ) jtd 
STRAIGHT_JOIN 
     JBPM_TIMER jt FORCE INDEX (ix_JBPM_TIMER_priority_duedate) 
ON  jt.priority >= jtd.priority 
     AND jt.priority <= jtd.priority 

Vous devez créer un index sur (priority, duedate):

CREATE INDEX ix_JBPM_TIMER_priority_duedate ON JBPM_TIMER (priority, duedate) 

Notez que contrairement à votre solution originale, ce vraiment est un hack vilain dont le comportement peut changer dans les prochaines versions de MySQL.

Je l'affiche ici seulement comme une solution de contournement si vous ne pouvez pas modifier votre schéma. Ne l'utilisez pas s'il y a une moindre chance que votre MySQL soit mis à jour.

+0

Ok, merci pour la réponse rapide. Nous avons réécrit le patch et nous utilisons maintenant -PRIORITY à la place. – Erik

Questions connexes