以下查询尽管有索引,并且id
是主键,但返回数据需要约15秒钟。
select id from my_table order by insert_date offset 0 limit 1
以下是解释分析:
"Limit (cost=1766417.72..1766417.72 rows=1 width=12) (actual time=32479.440..32479.441 rows=1 loops=1)"
" -> Sort (cost=1766417.72..1797117.34 rows=12279848 width=12) (actual time=32479.437..32479.437 rows=1 loops=1)"
" Sort Key: insert_date"
" Sort Method: top-N heapsort Memory: 25kB"
" -> Seq Scan on my_table (cost=0.00..1705018.48 rows=12279848 width=12) (actual time=0.006..21338.401 rows=12108916 loops=1)"
"Total runtime: 32479.476 ms"
我的表格还有其他几列,但是insert_date
的类型是
insert_date timestamp without time zone NOT NULL DEFAULT now(),
我在那个特定日期列上有一个索引,它是:
CREATE INDEX my_table_insert_date_indx
ON my_table
USING btree
(insert_date)
TABLESPACE somexyz_idx_ts;
postgresql.conf
文件中的几个值:
shared_buffers = more than 1GB ## just for an example
temp_buffers = more than 1GB
work_mem = more than 1GB
maintenance_work_mem = more than 1GB
dynamic_shared_memory_type = posix
default_statistics_target = 10000
autovacuum = on
random_page_cost = 2.0
cpu_index_tuple_cost = 0.0005
我现在正在使用Postgres 9.3。
更新:
刚刚执行了以下查询:
select insert_date, count(*) from my_table group by insert_date
搜索结果的前几个为:
"2015-04-02 00:00:00";3718104
"2015-04-03 00:00:00";6410253
"2015-04-04 00:00:00";538247
"2015-04-05 00:00:00";1228877
"2015-04-06 00:00:00";131248
我在那张表上大约有1200万条记录。而上面的计数几乎接近于总数。
不确定,但是可能问题出在索引被创建在一个有大量重复值的列上。如果是这样,我们有什么解决方法吗?
set enable_seqscan = off;
测试相同的查询,并显示解释分析输出。你的索引和表有多大?在 psql 中使用\di+ my_table_insert_date_indx
、\dt+ my_table
命令可以显示大小。 - alexius23 GB
,索引大小为293 MB
。 - Sabuj Hassan