Индекс postgres неясен - PullRequest
       51

Индекс postgres неясен

0 голосов
/ 25 февраля 2019

Я недавно столкнулся и решил проблему - но я не понимаю, почему вообще возникла проблема.

Упрощенно сказано, у меня есть 3 таблицы в базе данных postgres 10.5:

entities (id, name)
entities_to_stuff(
    id, 
    entities_id -> fk entities.id, 
    stuff_id -> fk stuff.id, 
    unique constraint (entity_id, stuff_id)
)
stuff(id, name)

после вставки около 200 тыс. Записей выбирает по запросу:

select * from entities_to_stuff where entities_id = 1;

начало занимать 100 - 400 мс.

Как понятно, создание уникального ограничения создает индекс по уникальным полям.поэтому у меня есть индекс на (entities_id, stuff_id), entities_id - самый левый столбец.

в соответствии с документами, запросы, включая самый левый столбец, являются наиболее эффективными ( postgres документы на этом ) - поэтому я предположил, что этот индекс мне подойдет.

Итак, я проверил план выполнения - он не использовал индекс.Итак, просто чтобы убедиться, что я сделал:

SET enable_seqscan = OFF;

и повторно выполнил запрос - большую часть времени он все еще занимал более 100 мс.

Затем я разозлился и создал этот индекс

create index "idx_entities_id" on "entities_to_stuff" ("entities_id");

и внезапно для запуска требуется 0,2 мс или даже меньше, и план выполнения также использует его, когда включены последовательные сканирования.

Как этот индекс на несколько порядков быстрее, чем ужесуществующий?

Редактировать:

план выполнения после генерации дополнительного индекса:

Index Scan using idx_entities_id on entities_to_stuff (cost=0.00..12.04 rows=2 width=32) (actual time=0.049..0.050 rows=1 loops=1)
  Index Cond: (entities_id = 199283)
Planning time: 0.378 ms
Execution time: 0.073 ms

план только с уникальным ограничением, seq_scan = on

Gather  (cost=1000.00..38679.87 rows=2 width=32) (actual time=344.321..1740.861 rows=1 loops=1)
  Workers Planned: 2
  Workers Launched: 0
  ->  Parallel Seq Scan on entities_to_stuff  (cost=0.00..37679.67 rows=1 width=32) (actual time=344.088..1739.684 rows=1 loops=1)
        Filter: (entities_id = 199283)
        Rows Removed by Filter: 2907419
Planning time: 0.241 ms
Execution time: 740.888 ms

план с ограничением, seq-scan = off

Index Scan using uq_entities_to_stuff on entities_to_stuff  (cost=0.43..66636.34 rows=2 width=32) (actual time=0.385..553.066 rows=1 loops=1)
  Index Cond: (entities_id = 199283)
Planning time: 0.082 ms
Execution time: 553.103 ms
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...