Index Only Scan в Postgresql 9.2
Вообще, сам не узнаю себя, уже ровно месяц прошел с выпуска Postgresql 9.2, даже вышло обновление 9.2.1, исправляющее некоторые баги, а я все еще ничего не написал об этом.
Поэтому сегодня рассказ будет о Index Only Scan — самом заметном, по моему мнению, изменении в 9.2. Кстати, именно это изменение стоит первым в Release Notes, а значит я не одинок.
Проблема с проверкой уникальности какого-то поля в rails
Пусть в модели User у нас описана валидация для поля email
validates_uniqueness_of :email, :case_sensitive => false,
:message => i18n_proxy(:email_already_registered)
Следующий код генерирует вот такой запрос к базе данных:
SELECT * FROM users WHERE lower(email) = 'thmth' LIMIT 1
А на таблице users у нас индекс по полю email. В postgresql запрос, что вверху, не будет использовать индекс. Представьте, что будет, когда в таблице users десятки тысяч записей, а на каждое изменение любого поля в users вызывается такой запрос.
Именно это я наблюдал совсем недавно на нашей живой базе. Проблема решается
просто, например, убрать :case_sensetive
, а email всегда
предварительно переводить в нижние буквы.
Конкурентное пересоздание индексов в postgresql
На таблице postgresql с большим количеством данных невозможно быстро создать либо пересоздать индекс. При создании индекса таблица блокируется для операций INSERT, UPDATE и DELETE. В таких случаях может помочь конкурентное создание индекса. Иногда на postgresql стоит пересоздавать индексы, чтобы уменьшить их фрагментацию (и увеличить скорость). Создание конкурентного индекса будет частным случаем его пересоздания.
Пусть имеется таблица orders с 1 миллионом записей (приблизительно) в которой хранятся заказы. И в этой таблице есть поля country_id, region_id, city_id, на которых создан индекс.