При пустой таблице любое обсуждение настройки производительности является теоретическим. Чтобы действительно что-то знать наверняка, вам нужно поместить много данных в таблицу и сделать эти данные такими же реалистичными, как и набор производственных данных, который вы можете разумно придумать.
Тем не менее, на теорию ...
Таблица сканирования по сравнению с индексом
При пустой таблице наиболее эффективным планом выполнения обычно будет полное сканирование таблицы. Зачем? Начальные затраты / накладные расходы на полный комплект очень низкие.
Использование индекса имеет высокие накладные расходы (то есть базовую стоимость простого поиска независимо от того, что найдено), но чрезвычайно низкую стоимость на строку. Полное сканирование таблицы имеет чрезвычайно низкую нагрузку при максимальной стоимости за строку. С учетом сказанного есть два практических правила:
- Чем меньше таблица, тем менее полезен индекс.
- Чем более выборочный индексный поиск, тем он полезнее. Поиск по индексу, который затем соответствует 90% строк в таблице, очень неэффективен, и СУБД, как правило, достаточно умны, чтобы этого не делать.
Оценки и статистика
Учитывая приведенные выше практические правила, для того чтобы СУБД могла решить, какой план является наиболее эффективным, ей необходимо знать некоторые детали данных, в частности, количество строк в таблице и количество строк в запросе. скорее всего, совпадет.
Мы получаем подвох-22, потому что ему нужно запросить данные, чтобы выяснить, сколько данных вернется, чтобы он мог выбрать наиболее эффективный план запроса.
Таким образом, все это работает так, что СУБД, как и Postgres, хранит статистику о данных, которые планировщик запросов может использовать. Эти статистические данные точны в определенные моменты времени и являются оценочными. Пример статистики:
- Приблизительное количество строк для таблицы
- Для индекса приблизительное количество строк для каждого ключа
- Частота определенных значений в столбце
Опять же, помните, что это оценки. Для Postgres гарантировать точность статистики всегда очень дорого, но нам не нужна высокая точность при выборе плана выполнения. Разница между таблицей из 1 строки и таблицей из 2 строк несущественна. Но таблица с 1 строкой или таблица с миллионами строк или таблица с миллионами строк имеют большое значение.
Хорошее чтение здесь: https://www.postgresql.org/docs/9.6/static/planner-stats.html
Краткое описание
Учитывая все вышесказанное, Postgres, вероятно, точно не знает, сколько строк в вашей таблице, но знает, что она мала. Поэтому пороговое значение для использования индекса высокое, поэтому ваш первый запрос выполняет сканирование таблицы. Со второй проверкой даты, вероятно, будет вычислено, что запрос будет соответствовать меньшему количеству строк, когда он проверяет индекс первичного ключа, поэтому он идет для индекса.