PostgreSQL создает для каждого запроса план выполнения на основе оценки "стоимости" выборки и просмотра данных. Последовательный просмотр всех строк таблицы по мере увеличения количества строк становится слишком дорогостоящим.
Команда EXPLAIN
Для определения стоимости в PostgrSQL существует команда EXPLAIN, ниже приведен пример:
mydb=# EXPLAIN SELECT * FROM words WHERE word='multi';
NOTIE: QUERY PLAN:
Seq Scan on words (cost=0.00..22.50 rows=10 width=12)
EXPLAIN
mydb=#
Этот запросы выполнен на тестовой базе в 45.000 строк со словами (обычный словарь), как видно максимальная стоимость такого запроса 22,5, однако это далеко не так.
Команда VACUUM
Если в этой же базе выполнить команду VACUUM, а потом снова EXPLANI запроса
mydb=# VACUUM ANALYZE words;
VACUUM
mydb=# EXPLAIN SELECT * FROM words WHERE word='multi';
NOTIE: QUERY PLAN:
Seq Scan on words (cost=0.00..843.59 rows=10 width=12)
EXPLAIN
mydb=#
Теперь стоимость запроса поднялась до 843, все потому что при первом выполнении мы использовали старую статистику а команда VACUUM позволила её обновить а как результат более точная оценка запроса. Особенно эта команда актуальна после множества изменений (INSERT/UPDATE и т.п.) в таблице.
Комманда CREATE INDEX
Для ускорения этого запроса можно построить индексы, т.к. затраты на просмотр индексов значительно меньше чем полный перебор.
Создание индекса:
CREATE [unique] INDEX indexname ON table(column)
Параметр unique указывает, что индексируемый столбец не содержит повторяющихся записей, все строки имеют уникальные значения в данном столбце. Используйте этот параметр (unique) только в случае полной уверенности в том, что в столбце никогда не появятся повторяющиеся данные. Например:
mydb=# CREATE INDEX words_idx ON words(word);
CREATE
Теперь посмотрим на план запроса:
mydb=# EXPLAIN SELECT * FROM words WHERE word='multi';
NOTIE: QUERY PLAN:
Seq Scan on words (cost=0.00..2.09 rows=10 width=12)
EXPLAIN
mydb=#
Такой запрос будет выполнен практически мгновенно, в отличии от 843 когда наблюдается существенная задержка.
Всегда стоит рассматривать создание индексов для:
* Таблиц, состоящих из большого количества редко обновляющихся строк.
* Столбцов, не являющихся первичными или внешними ключами, которые могут использоваться в сложных объединениях.
* Столбцов, которые будут просматриваться в поиске точного совпадения префиксов.
Разумеется в оптимизации хороша "золотая середина" так как от создания индексов есть и отрицательный момент - большое количество потребляемого места, а оно разумеется не резиновое.