我有下表非常大。 (> 100万行)
create table DataPoint (id int8 not null,
time timestamp not null,
value float8, dataFile_id int8 not null,
type_id int8 not null, primary key (id));
我所有的其他表都小得多(<1000)行。
我尝试提高以下查询的性能:
select dp.id, dp.value, dp.time
from DataPoint dp
inner join DataFile datafile2_ on dp.dataFile_id=datafile2_.id
inner join DataType datatype4_ on dp.type_id=datatype4_.id
where dp.dataFile_id=? and dp.type_id=?
and dp.value is not null order by dp.time asc limit 1
我已经有了dp.dataFile_id的索引。查询花了大约500毫秒。 然后我在dp.type_id上添加了一个索引,将时间减少到大约40ms。
但是当我在dp.time上添加一个额外的索引时,查询突然需要2500毫秒! 删除索引使时间回到30-40ms。我发现很难理解添加索引如何降低查询的性能。
答案 0 :(得分:1)
这两个索引都可以用于此查询。为什么选择一个而不选择另一个取决于各种因素,例如数据库保留的关于表的统计信息。
但是,此查询的最佳索引是DataPoint(dataFile_id, type_id, value, time)
上的综合索引。
答案 1 :(得分:0)
使用time
索引,PostgreSQL认为使用该索引以time
顺序遍历行时最快,并在符合其他条件的第一行停止。 / p>
它似乎实际上必须遍历表的大部分才能找到第一行,因为符合条件的行都在较晚的时间段内,没有一个在早期时间段。但PostgreSQL并不知道,这就是它被愚弄使用较慢的索引的方式。
正如戈登林诺夫回答的那样,你可能会从综合指数中受益。