【发布时间】:2016-04-05 21:51:32
【问题描述】:
在我的 postgreSQL 数据库中,我有一个名为 "product" 的表。在此表中,我有一个名为 "date_touched" 的列,类型为 timestamp。我在此列上创建了一个简单的 btree 索引。这是我的表的架构(我省略了不相关的列和索引定义):
Table "public.product"
Column | Type | Modifiers
---------------------------+--------------------------+-------------------
id | integer | not null default nextval('product_id_seq'::regclass)
date_touched | timestamp with time zone | not null
Indexes:
"product_pkey" PRIMARY KEY, btree (id)
"product_date_touched_59b16cfb121e9f06_uniq" btree (date_touched)
该表有约 300,000 行,我想从由"date_touched" 排序的表中获取第 n 个元素。当我想得到第 1000 个元素时,需要 0.2s,但是当我想得到第 100,000 个元素时,大约需要 6s。我的问题是,为什么检索第 100,000 个元素需要太多时间,尽管我已经定义了一个 btree 索引?
这是我对 explain analyze 的查询,显示 postgreSQL 不使用 btree 索引,而是对所有行进行排序以找到第 100,000 个元素:
- 第一个查询(第 100 个元素):
explain analyze
SELECT product.id
FROM product
ORDER BY product.date_touched ASC
LIMIT 1
OFFSET 1000;
QUERY PLAN
-----------------------------------------------------------------------------------------------------
Limit (cost=3035.26..3038.29 rows=1 width=12) (actual time=160.208..160.209 rows=1 loops=1)
-> Index Scan using product_date_touched_59b16cfb121e9f06_uniq on product (cost=0.42..1000880.59 rows=329797 width=12) (actual time=16.651..159.766 rows=1001 loops=1)
Total runtime: 160.395 ms
- 第二个查询(第 100,000 个元素):
explain analyze
SELECT product.id
FROM product
ORDER BY product.date_touched ASC
LIMIT 1
OFFSET 100000;
QUERY PLAN
------------------------------------------------------------------------------------------------------
Limit (cost=106392.87..106392.88 rows=1 width=12) (actual time=6621.947..6621.950 rows=1 loops=1)
-> Sort (cost=106142.87..106967.37 rows=329797 width=12) (actual time=6381.174..6568.802 rows=100001 loops=1)
Sort Key: date_touched
Sort Method: external merge Disk: 8376kB
-> Seq Scan on product (cost=0.00..64637.97 rows=329797 width=12) (actual time=1.357..4184.115 rows=329613 loops=1)
Total runtime: 6629.903 ms
【问题讨论】:
-
看起来像这里提到的类似问题?检查您的 Postgres 和机器配置。 postgresql.org/message-id/…
标签: sql postgresql query-performance sql-execution-plan b-tree