说明:
我有一张桌子tickets
。它有一个主键ticket_no
,它是一个varchar
。因为它是主键,所以它也有索引。我有两个使用通配符的简单查询,对所测得的性能结果感到惊讶,我无法解释。我正在使用Postgres数据库。
1。)在字符串末尾使用通配符查询:
SELECT * FROM tickets WHERE ticket_no LIKE '000543200099%';
2。)在字符串的开头使用通配符查询:
SELECT * FROM tickets WHERE ticket_no LIKE '%005432000998';
期望:
我认为,以通配符结尾的第一个查询的执行时间会更快,因为该属性具有索引,并且可以进行索引扫描以查找所有条目匹配通配符字符串。 第二个查询必须更慢,因为在开始时使用通配符必须使用 Sequence Scan 检查表的全部,这显然要比 Index Scan 慢。 strong>。
结果:
原来,这两个查询都同样快。检查序列图,结果发现对两个查询都进行了序列扫描。我真的不明白为什么对第一个查询执行 Sequence Scan (序列扫描)而不是对 Index Scan 进行索引扫描。为什么会这样呢?
编辑:
在此使用表的DDL:
create table if not exists tickets
(
ticket_no varchar not null
constraint tickets_pkey
primary key,
book_ref char(6) not null
constraint tickets_book_ref_fkey
references bookings,
passenger_id varchar(20) not null,
passenger_name text not null,
contact_data jsonb
)
对于索引:
create unique index if not exists tickets_pkey
on tickets (ticket_no);
这是两个查询的EXPANAI ANAYLZE,如您所见,除了边际时间差之外,它们是相同的:
1。)
EXPLAIN ANALYZE SELECT * FROM tickets WHERE ticket_no LIKE '000543200099%';
=>
Gather (cost=1000.00..67253.74 rows=14749 width=122) (actual time=0.748..219.487 rows=10 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Parallel Seq Scan on tickets (cost=0.00..64778.84 rows=6145 width=122) (actual time=128.056..199.550 rows=3 loops=3)
Filter: ((ticket_no)::text ~~ '000543200099%'::text)
Rows Removed by Filter: 983282
Planning Time: 1.182 ms
Execution Time: 219.512 ms
2。)
EXPLAIN ANALYZE SELECT * FROM tickets WHERE ticket_no LIKE '%005432000998';
=>
Gather (cost=1000.00..65808.34 rows=295 width=122) (actual time=0.768..276.445 rows=1 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Parallel Seq Scan on tickets (cost=0.00..64778.84 rows=123 width=122) (actual time=133.961..224.468 rows=0 loops=3)
Filter: ((ticket_no)::text ~~ '%005432000998'::text)
Rows Removed by Filter: 983285
Planning Time: 0.117 ms
Execution Time: 276.460 ms