PostgreSQL üblichen Index nicht für Operator LIKE
verwendet
postgres=# create index on obce(nazev);
CREATE INDEX
Time: 120.605 ms
postgres=# explain analyze select * from obce where nazev like 'P%';
┌─────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ QUERY PLAN │
╞═════════════════════════════════════════════════════════════════════════════════════════════════════╡
│ Seq Scan on obce (cost=0.00..137.12 rows=435 width=41) (actual time=0.023..2.345 rows=450 loops=1) │
│ Filter: ((nazev)::text ~~ 'P%'::text) │
│ Rows Removed by Filter: 5800 │
│ Planning time: 0.485 ms │
│ Execution time: 2.413 ms │
└─────────────────────────────────────────────────────────────────────────────────────────────────────┘
(5 rows)
Sie sollten spezielle Syntax mit varchar_pattern_ops
Stichwort
postgres=# create index on obce(nazev varchar_pattern_ops);
CREATE INDEX
Time: 124.709 ms
postgres=# explain analyze select * from obce where nazev like 'P%';
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ QUERY PLAN │
╞═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╡
│ Bitmap Heap Scan on obce (cost=12.39..76.39 rows=435 width=41) (actual time=0.291..0.714 rows=450 loops=1) │
│ Filter: ((nazev)::text ~~ 'P%'::text) │
│ Heap Blocks: exact=58 │
│ -> Bitmap Index Scan on obce_nazev_idx1 (cost=0.00..12.28 rows=400 width=0) (actual time=0.253..0.253 rows=450 loops=1) │
│ Index Cond: (((nazev)::text ~>=~ 'P'::text) AND ((nazev)::text ~<~ 'Q'::text)) │
│ Planning time: 0.953 ms │
│ Execution time: 0.831 ms │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
(7 rows)
Aber dieses doesn verwenden‘ t Arbeit für ILIKE - die Problemumgehung kann Funktionsindex sein:
create index on obce(upper(nazev) varchar_pattern_ops);
select * from obce where upper(nazev) like upper('P%');
Hinweis: "Název" ist der Name in der tschechischen Sprache
Eine weitere Möglichkeit pg_trgm Erweiterung und mit trigram Index verwendet. Es funktioniert für beide LIKE
, ILIKE
, aber der Index ist viel größer - es ist kein Problem für relativ kleine statische Tabellen.
create extension pg_trgm ;
create index on obce using gin (nazev gin_trgm_ops);
postgres=# explain analyze select * from obce where nazev like 'P%';
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ QUERY PLAN │
╞═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╡
│ Bitmap Heap Scan on obce (cost=15.37..79.81 rows=435 width=41) (actual time=0.327..0.933 rows=450 loops=1) │
│ Recheck Cond: ((nazev)::text ~~ 'P%'::text) │
│ Rows Removed by Index Recheck: 134 │
│ Heap Blocks: exact=58 │
│ -> Bitmap Index Scan on obce_nazev_idx1 (cost=0.00..15.26 rows=435 width=0) (actual time=0.287..0.287 rows=584 loops=1) │
│ Index Cond: ((nazev)::text ~~ 'P%'::text) │
│ Planning time: 0.359 ms │
│ Execution time: 1.056 ms │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
(8 rows)
Kennen Sie [ 'Database_index'] (https://en.wikipedia.org/wiki/Database_index) und eine [' Postgresql Funktion explain'] (https://www.postgresql.org/ docs/9.4/statisch/using-explain.html)? –
@ Citiesелёный Cities-Tabelle verfügt über einen Datenbankindex für die Spalte "Name". Ich bin nicht vertraut mit "PostgreSQL erklären" – Mahendhar
gut dann sollten Sie es nachschlagen. Link ist in @ Зелёныйs Kommentar – e4c5