TL; DR: В свете вашего наиболее частого запроса вы должны индексировать (user_type, modifiedon)
. Если вы опустите первый столбец, индекс будет неоптимальным, но все же полезным.
Подумайте, как организованы данные в индексе: по сути, это отсортированный список, упорядоченный сначала по первому столбцу индекса, а затем - ndash; в пределах каждой группы равных значений первого столбца & ndash; по второму столбцу индекса.
Так что если вы индексируете по (modifiedon, usertype)
, индекс будет выглядеть примерно так:
modifiedon | usertype
------------+-------------
2018-01-01 | basicuser
2018-01-01 | normaluser
2018-01-01 | superuser
2018-01-01 | .........
2018-01-02 | normaluser
2018-01-02 | .........
.......... | .........
2018-04-29 | basicuser
2018-04-29 | normaluser
2018-04-29 | xpertuser
Сканирование индекса можно использовать только в том случае, если искомые данные образуют непрерывный блок записей в индексе.
Теперь, если ваш запрос
SELECT * FROM user WHERE modifiedon BETWEEN $1 AND $2 AND usertype = $3;
индекс можно использовать для первых условий, поскольку записи для modifiedon
между двумя датами образуют непрерывный блок записей индекса. Однако индекс не может использоваться для второго условия, поскольку записи индекса для определенного usertype
не находятся рядом друг с другом в блоке, выбранном первым условием.
Однако, если у вас есть индекс на (usertype, modifiedon)
, он будет выглядеть так:
usertype | modifiedon
------------+-------------
basicuser | 2018-01-01
basicuser | 2018-01-02
basicuser | ..........
basicuser | 2018-04-29
normaluser | 2018-01-01
normaluser | 2018-01-02
normaluser | ..........
normaluser | 2018-04-29
.......... | ..........
xpertuser | 2018-03-01
xpertuser | ..........
xpertuser | 2018-04-29
Очевидно, что записи, соответствующие запросу, образуют непрерывный блок записей в индексе, поэтому его можно использовать для всего условия .
Таким образом, этот комбинированный индекс является лучшим индексом для запроса.
Однако, может быть, очень мало usertype
с. Тогда второе условие не очень избирательно, и нет большой выгоды от включения столбца usertype
в индекс. На самом деле, это может быть вредно, поскольку увеличивает индекс, а это означает, что во время сканирования индекса потребуется больше работы, чтобы вы могли эффективно потерять его.