Выбор ответа Middle EXPLAIN и оптимизация обновлено

Seq Scan при выборке 90% строк

Вопрос

Запрос SELECT * FROM orders WHERE status = 'paid' вернул 900 тысяч строк из миллиона. Коллега предлагает создать индекс по status. Что изменится в плане?

Seq Scan on orders  (cost=0.00..19908.00 rows=898433 width=32) (actual time=0.029..143.411 rows=900000 loops=1)
  Filter: (status = 'paid'::text)
  Rows Removed by Filter: 100000
Planning Time: 1.208 ms
Execution Time: 165.897 ms

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Скорее ничего: при 90% строк Seq Scan дешевле, его и оставят. Индекс выгоден, когда условию соответствует малая доля строк.

Варианты ответа

  1. Скорее ничего: при 90% строк Seq Scan дешевле, его и оставятправильный ответ
  2. Планировщик выберет Index Scan, и запрос ускорится примерно в 10 раз
  3. Планировщик выберет Index Only Scan, потому что status в индексе
  4. Seq Scan станет параллельным, потому что появится индекс по колонке

Разбор

Индекс выгоден, когда условию соответствует малая доля строк. Здесь нужно 90% таблицы: читать её подряд большими блоками быстрее, чем для каждой строки идти из индекса в случайное место кучи. Планировщик оценивает это через стоимость (random_page_cost против seq_page_cost) и оставит Seq Scan. Index Only Scan невозможен: запрос просит *, а не только status. Индекс по status мог бы помочь для редкого значения, например cancelled (2%), а ещё лучше частичный индекс под конкретный запрос. На параллельность индекс не влияет.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме