我的postgres数据库中有一个简单的表结构:
CREATE TABLE device
(
id bigint NOT NULL,
version bigint NOT NULL,
device_id character varying(255),
date_created timestamp without time zone,
last_updated timestamp without time zone,
CONSTRAINT device_pkey PRIMARY KEY (id )
)
我经常根据deviceId列查询数据。该表有3,5万行,因此会导致性能问题:
"Seq Scan on device (cost=0.00..71792.70 rows=109 width=8) (actual time=352.725..353.445 rows=2 loops=1)"
" Filter: ((device_id)::text = '352184052470420'::text)"
"Total runtime: 353.463 ms"
因此我在device_id列上创建了索引:
CREATE INDEX device_device_id_idx
ON device
USING btree
(device_id );
但问题是,该数据库仍然使用顺序扫描,而不是索引扫描。创建索引后的查询计划是相同的:
"Seq Scan on device (cost=0.00..71786.33 rows=109 width=8) (actual time=347.133..347.508 rows=2 loops=1)"
" Filter: ((device_id)::text = '352184052470420'::text)"
"Total runtime: 347.538 ms"
查询的结果是2行,所以我没有选择表的大部分内容。我真的不明白为什么索引被忽视了。我该怎么做才能提高性能?
编辑:
我的查询:
select id from device where device_id ='357560051102491A';
我在设备表上运行analyse
,这没有帮助
device_id也包含字符。
答案 0 :(得分:0)
您可能需要查看查询。要使用索引,查询需要是可搜索的。这意味着构建查询的某些方法比其他方式更好。我不熟悉Postgre,但是在SQl Server中,这将包含这样的东西(非常小的错误构造样本):
您的第一步应该是为您的特定数据库获得一本关于性能调优的好书。它将讨论为特定数据库引擎要避免的构造。
答案 1 :(得分:0)
将列转换为其他类型时不使用索引:
((device_id)::text = '352184052470420'::text)
相反,你可以这样做:
(device_id = ('352184052470420'::character varying))
(或者如果您愿意,也可以将原始表格中的device_id更改为TEXT。)
此外,请记住在创建索引后运行analyze device
,否则无论如何都不会使用它。
答案 2 :(得分:0)
似乎,就像时间解决了一切。我不确定发生了什么,但目前工作正常。 从我发布这个问题开始,我没有改变任何内容,现在我得到了这个查询计划:
"Bitmap Heap Scan on device (cost=5.49..426.77 rows=110 width=166)"
" Recheck Cond: ((device_id)::text = '357560051102491'::text)"
" -> Bitmap Index Scan on device_device_id_idx (cost=0.00..5.46 rows=110 width=0)"
" Index Cond: ((device_id)::text = '357560051102491'::text)"
时间分解(时区GMT + 2):
analyse device
(没有帮助)问题仍然存在,为什么需要大约1:10小时才能应用索引?几天前,当我在同一个数据库中创建索引时,立即进行了更改。