我在 PostgreSQL 9.1 中做了一个简单的实验。我创建test
的表如下:
CREATE TABLE test
(
id serial NOT NULL,
CONSTRAINT id PRIMARY KEY (id )
)
CREATE INDEX id_idx
ON test
USING btree
(id );
然后我添加一些数据:
insert into test values(DEFAULT);
insert into test values(DEFAULT);
insert into test values(DEFAULT);
...many times :)
现在我有test
一张有 10'000 行的表格。我的第一个实验是通过id
:
explain select * from test where id = 50;
Index Scan using id_idx on test (cost=0.00..8.27 rows=1 width=4)
Index Cond: (id = 50)
好的,这里没什么奇怪的。让我们按值范围进行查询:
explain select * from test where id >= 50;
Seq Scan on test (cost=0.00..170.00 rows=9951 width=4)
Filter: (id >= 50)
我们通过顺序扫描获得了 9951 行,但如果我只想获得第一个行怎么办:
explain select * from test where id >= 50 limit 1;
Limit (cost=0.00..0.02 rows=1 width=4)
-> Seq Scan on test (cost=0.00..170.00 rows=9951 width=4)
Filter: (id >= 50)
我希望看到索引扫描rows=1
,但我再次进行了顺序扫描(扫描后有限制)。有什么方法可以通过 SQL 查询实现这种行为?
注意:我有类似的 MongoDB 查询:
> db.test.find({'dt':{$gte:ISODate("2013-07-20T00:00:00.00Z")}}).count()
10000
> db.test.find({'dt':{$gte:ISODate("2013-07-20T00:00:00.00Z")}}).limit(1).explain()
{
"cursor" : "BtreeCursor dt_1",
"isMultiKey" : false,
"n" : 1,
"nscannedObjects" : 1,
"nscanned" : 1,
"nscannedObjectsAllPlans" : 1,
"nscannedAllPlans" : 1,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 13,
"indexBounds" : {
"dt" : [
[
ISODate("2013-07-20T00:00:00Z"),
ISODate("0NaN-NaN-NaNTNaN:NaN:NaNZ")
]
]
},
"server" : "******:27017"
}
在这种情况下,MongoDB 使用索引扫描仅扫描了 1 个文档,这很棒。