我正在调试一个查询,它返回的记录越多,运行速度就越快,但是使用小LIMIT
(即10),返回越少(即〈10行),性能就会严重下降(慢10倍以上)。
示例:
快速查询,100万行中有5个结果-无限制
SELECT *
FROM transaction_internal_by_addresses
WHERE address = 'foo'
ORDER BY block_number desc;
解释:
Sort (cost=7733.14..7749.31 rows=6468 width=126) (actual time=0.030..0.031 rows=5 loops=1)
" Output: address, block_number, log_index, transaction_hash"
Sort Key: transaction_internal_by_addresses.block_number
Sort Method: quicksort Memory: 26kB
Buffers: shared hit=10
-> Index Scan using transaction_internal_by_addresses_pkey on public.transaction_internal_by_addresses (cost=0.69..7323.75 rows=6468 width=126) (actual time=0.018..0.021 rows=5 loops=1)
" Output: address, block_number, log_index, transaction_hash"
Index Cond: (transaction_internal_by_addresses.address = 'foo'::text)
Buffers: shared hit=10
Query Identifier: -8912211611755432198
Planning Time: 0.051 ms
Execution Time: 0.041 ms
快速查询,100万行中有5个结果:- 上限
一个二个一个一个
查询速度慢:-下限
SELECT *
FROM transaction_internal_by_addresses
WHERE address = 'foo'
ORDER BY block_number desc
LIMIT 10;
解释结果:
Limit (cost=7570.95..7571.20 rows=100 width=126) (actual time=0.989..0.990 rows=5 loops=1)
" Output: address, a_indexed_row, log_index, transaction_hash"
Buffers: shared hit=2 read=8
-> Sort (cost=7570.95..7587.12 rows=6468 width=126) (actual time=0.987..0.988 rows=5 loops=1)
" Output: address, a_indexed_row, log_index, transaction_hash"
Sort Key: a_table.a_indexed_row DESC
Sort Method: quicksort Memory: 26kB
Buffers: shared hit=2 read=8
-> Index Scan using a_table_pkey on public.a_table (cost=0.69..7323.75 rows=6468 width=126) (actual time=0.592..0.981 rows=5 loops=1)
" Output: address, a_indexed_row, log_index, transaction_hash"
Index Cond: (a_table.address = 'foo'::text)
Buffers: shared hit=2 read=8
Query Identifier: 3421253327669991203
Planning Time: 0.093 ms
Execution Time: 1.002 ms
- DDL公司**
create table transaction_internal_by_addresses
(
address text not null,
block_number bigint,
log_index bigint not null,
transaction_hash text not null,
primary key (address, log_index, transaction_hash)
);
alter table transaction_internal_by_addresses
owner to "icon-worker";
create index transaction_internal_by_address_idx_block_number
on transaction_internal_by_addresses (block_number);
所以我的问题
- 我应该只考虑强制查询计划器对
address
(主键)应用WHERE的方法吗? - 正如您在解释中所看到的,行
block_number
在慢速查询中被扫描,但我不知道为什么。有人能解释一下吗? - 这正常吗?似乎数据越多,查询就越困难,而不是像本例中那样相反。
谢谢你抽出时间。
1条答案
按热度按时间bf1o4zei1#
亚毫秒级的差异很难预测,所以你几乎只能看到噪音,以及系统上发生的其他事情所导致的随机微小差异。你最快的查询运行时间为数十微秒,最慢的为一毫秒 -所有这些都低于典型的网络、鼠标点击、屏幕刷新延迟。
1.计划程序已经在您的
address
上应用了where
: 指数条件:(a_表格.地址= 'foo'::文本)*1.您是按
block_number
排序的,所以扫描它是有意义的,而且这也发生在您的所有三个查询中,因为它们都这样做。pgbench
多次运行你的查询,并计算出时间的平均值。您的第三个查询计划似乎来自针对不同表的不同查询:
a_table
,与前两个相比:transaction_internal_by_addresses
.如果你只是想知道为什么这些时间看起来像这样,它在这个层次上几乎是随机的和/或不相关的。如果你因为这些查询的行为而面临某种问题,最好集中精力描述这个问题-查询本身都做同样的事情,它们的执行时间差异可以忽略不计。