注意事项:表/列/索引名称由组成。
背景
我在弄清楚如何高效地查询我的数据库表(该表有大约一百万行)时遇到了一些困难。所讨论的查询涉及带有外键的WHERE子句和带有另一列的ORDER BY子句。
数据库在FK上生成一个索引,我在用于排序的列上创建一个索引:
CREATE INDEX ab ON a(b);问题
当我在不过滤FK的情况下运行查询时:
EXPLAIN SELECT * FROM a ORDER BY b;数据库正确地使用索引进行排序。我之所以知道这一点,是因为此查询的结果(截断)返回:
FROM PUBLIC.A
/* PUBLIC.AB */
ORDER BY 3
/* index sorted */但是,当将查询修改为在FK上筛选时:
EXPLAIN SELECT * FROM a WHERE a_fk_id = 3 ORDER BY b只使用FK索引:
FROM PUBLIC.A
/* PUBLIC.A_FK_INDEX_NAME: A_FK_ID = 3 */
WHERE A_FK_ID = 3
ORDER BY 3如您所见,只使用FK索引。
问题
这里发生什么事情?
我认为这可能与单独的索引有关,但甚至创建了一个多列索引,如:
CREATE INDEX a_fk_id_b ON a(a_fk_id, b);没有解决这个问题(也没有逆转索引中这些列的顺序,但我没有预料到)。
如有任何建议,将不胜感激。我绝不是一个数据库或SQL专家,但我惊讶地得到了这些结果。也许我只需要以不同的方式查询这些信息,但我认为这是一个相对简单的情况。
发布于 2015-11-04 17:49:12
答案很简单,虽然并不是很明显(至少对我来说不是这样)。该表需要在FK和order列之间有一个综合索引:
CREATE INDEX a_fk_id_b ON a(a_fk_id, b);为了使数据库能够利用该索引而不是生成的FK索引,a_fk_id列需要包含在ORDER BY子句中:
EXPLAIN SELECT * FROM a WHERE a_fk_id = 3 ORDER BY a_fk_id, b;这将导致我们的复合索引被用于筛选和排序,如这个截断的解释计划中所示:
FROM PUBLIC.A
/* PUBLIC.A_FK_ID_B: A_FK_ID = 3 */
WHERE A_FK_ID = 3
ORDER BY 25, 19
/* index sorted */ https://stackoverflow.com/questions/33525839
复制相似问题