Стоит ли использовать индексы при большом количестве вставок и малом количестве выборок
Что проверяют
Понимаете ли вы, что индекс не бесплатен: за ускорение чтения платят на каждой записи. Формулировка «стоит ли» проверяет умение рассуждать про профиль нагрузки, а не выдать заученное «индексы ускоряют запросы».
Как отвечать
Сначала уточните условие, в нём спрятана ловушка. «Мало выборок» не равно «выборок нет»: если по таблице в сотни миллионов строк раз в час идёт отчёт без индекса, это полное сканирование, которое вытесняет кэш и грузит диск сильнее, чем поддержка индекса на вставках.
Дальше разложите цену записи:
- каждый
INSERTдописывает запись в каждый индекс таблицы, а не только в сами данные; - вставка в случайное место B-дерева ведёт к расщеплению страниц и случайным записям на диск, тогда как возрастающий ключ ложится в конец;
- растёт объём журнала предзаписи, а с ним трафик репликации и время восстановления.
Затем скажите, что часть индексов не обсуждается вовсе: первичный ключ, уникальные ограничения и внешние ключи это правила целостности, их не снимают ради скорости вставки. Торговаться можно только вторичными индексами под редкие запросы.
Практический вывод: при массовой загрузке индексы снимают перед заливкой и строят заново после неё, одно построение дешевле миллиона дописываний. Для постоянного потока записи помогает секционирование по времени: свежая секция небольшая, и индекс по ней тоже.
Со стороны Java добавьте, что вставка часто упирается не в индексы, а в то, что Hibernate шлёт строки по одной. Включённая пакетная вставка и отказ от генератора IDENTITY, который её молча отключает, дают больше, чем снятый индекс.
Где спотыкаются
Отвечают лозунгом «много вставок, значит индексы не нужны», не спросив ни размера таблицы, ни того, какие запросы к ней ходят. Встречный вопрос тут и есть ожидаемая часть ответа.
Второе: снимают перед загрузкой уникальный индекс вместе с остальными, получают дубликаты и потом не могут построить его обратно. Ограничения целостности снимают только вместе с проверкой данных после заливки.
Третье: меряют эффект на пустой таблице. На тысяче строк разницы нет: она появляется, когда индекс перестаёт помещаться в память и каждое обращение к нему становится обращением к диску.