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 дешевле, его и оставятправильный ответ
- Планировщик выберет Index Scan, и запрос ускорится примерно в 10 раз
- Планировщик выберет Index Only Scan, потому что
statusв индексе - Seq Scan станет параллельным, потому что появится индекс по колонке
Разбор
Индекс выгоден, когда условию соответствует малая доля строк. Здесь нужно 90% таблицы: читать её подряд большими блоками быстрее, чем для каждой строки идти из индекса в случайное место кучи. Планировщик оценивает это через стоимость (random_page_cost против seq_page_cost) и оставит Seq Scan. Index Only Scan невозможен: запрос просит *, а не только status. Индекс по status мог бы помочь для редкого значения, например cancelled (2%), а ещё лучше частичный индекс под конкретный запрос. На параллельность индекс не влияет.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Предыдущий вопрос
Сколько строк вернул параллельный скан
Следующий вопрос
Почему в плане Bitmap Heap Scan, а не Index Scan