2009-08-10 58 views
2

失踪降序索引功能,我们有一个问题,它使用的jBPM的修改版本,具有优先支持我们的生产环境。目前指数:解决方法在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  |   | 

有问题的查询:

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) 

与PRIORITY_查询升序排列改为:

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) 

周围的Googling表明,解决的办法是添加另一列(REVERSEPRIORITY_),其中包含PRIORITY_ * -1的值并为其指定索引。在我看来,这似乎是一个非常丑陋的解决方案,所以我想问问你,如果你有更好的人!

+0

跟进的问题在这里:http://stackoverflow.com/questions/1256568/why-does-mysql-use-the-wrong-index – Erik 2009-08-10 18:53:02

回答

1

-PRIORITY是最好的解决方案。

但是,您可以使用MySQLFORCE INDEXSTRAIGHT_JOIN效仿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 

您需要在(priority, duedate)创建索引:

CREATE INDEX ix_JBPM_TIMER_priority_duedate ON JBPM_TIMER (priority, duedate) 

注意,与原来的解决方案,这真的是一个丑陋的黑客,其行为可以在MySQL的未来版本中改变。

我在这里张贴只是因为如果你不能改变你的模式的解决方法。

如果正在升级你的MySQL的机会丝毫不要使用它。

+0

好了,感谢您的快速答复。我们已经重写了这个补丁,现在我们使用-PRIORITY。 – Erik 2009-08-10 15:23:46