2

我有一个带有索引的表:

create index on foo (a, b, c);

在搜索 a 和 b 时,Postgres 可以使用索引快速查找行:

test=# explain analyze select a from foo where a = 3 and b = 4;
 Index Only Scan using foo_a_b_c_idx on foo  (cost=0.43..486.83 rows=120 width=4) (actual time=0.141..23.981 rows=59049 loops=1)
   Index Cond: ((a = 3) AND (b = 4))
   Heap Fetches: 59049
 Total runtime: 25.894 ms

虽然搜索 b 和 c 慢得多,因为它必须线性扫描整个索引(或表):

test=# explain analyze select a from foo where b = 4 and c = 5;
 Index Only Scan using foo_a_b_c_idx on foo  (cost=0.43..121987.32 rows=120 width=4) (actual time=7.377..159.793 rows=59049 loops=1)
   Index Cond: ((b = 4) AND (c = 5))
   Heap Fetches: 59049
 Total runtime: 160.735 ms

然而,查询计划在这两种情况下看起来是相等的(两者都称为“仅索引扫描”,带有一些“索引条件”)。是否可以判断是否可以在对数或线性时间内访问(无需查看每个索引定义)?

其他数据库系统更明确地说明它们如何使用索引。在 MS SQL 中,第一个查询是“Index Seek”(快),而第二个查询是“Index Scan”(慢)。在 Sqlite 中,第一个将是“使用覆盖索引的搜索表 foo”(快速),而第二个将是“使用覆盖索引的扫描表 foo”(慢)。

4

1 回答 1

3

除了@horse 强调的更详细的查询计划选项之外,答案是:不。除了对索引的工作原理有基本的了解(当然还有了解您自己的模式)之外,没有任何提示或方法可以知道。

于 2013-11-05T09:54:45.407 回答