首页 > 解决方案 > 不同位置的通配符,意外的顺序扫描而不是索引扫描

问题描述

描述:

我有一张桌子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慢。

结果:

事实证明,这两个查询都同样快。检查序列图,发现对两个查询都进行了序列扫描。我真的不明白为什么对第一个查询执行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);

这是两个查询的 EXPLAIN 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

标签: sqlpostgresqlperformancewildcard

解决方案


推荐阅读