为什么在表中添加索引会使查询变慢?

时间:2014-07-11 14:03:15

标签: sql postgresql database-performance

我有下表非常大。 (> 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。我发现很难理解添加索引如何降低查询的性能。

2 个答案:

答案 0 :(得分:1)

这两个索引都可以用于此查询。为什么选择一个而不选择另一个取决于各种因素,例如数据库保留的关于表的统计信息。

但是,此查询的最佳索引是DataPoint(dataFile_id, type_id, value, time)上的综合索引。

答案 1 :(得分:0)

使用time索引,PostgreSQL认为使用该索引以time顺序遍历行时最快,并在符合其他条件的第一行停止。 / p>

它似乎实际上必须遍历表的大部分才能找到第一行,因为符合条件的行都在较晚的时间段内,没有一个在早期时间段。但PostgreSQL并不知道,这就是它被愚弄使用较慢的索引的方式。

正如戈登林诺夫回答的那样,你可能会从综合指数中受益。