Комментарии 25
Тоже сталкивался с похожей проблемой — когда планировщик тупит и не использует индексы. pg_hint_planner не помог.
Чаще всего таки планировщик оказывается умнее человека :-)
И это прекрасно, очень приятно с Postgres-ом работать.
И это прекрасно, очень приятно с Postgres-ом работать.
А как это выяснить, кто прав — я или планировщик?
Я не знаю лучшего способа, чем выключить в конфиге стратегию, которая ему нравится, перезапустить сервер и сравнить cost запросов.
Вообще, если планировщик явно тупит, то первое, что стоит сделать — это ANALYZE таблицы. Ещё можно попробовать сбросить статистику планировщика и дать ей накопиться снова — мало ли, характер нагрузки на сервер изменился.
Но перед сбросом — подумать, почему PostgreSQL может себя так вести.
Например, у вас маленькая таблица, она в кеше — её проще перебрать так, действительно.
Или у вас неселективный запрос — тогда тоже проще считать всё и отфильтровать; потому что если постгрес сначала пойдет в индекс — ему после получения списка строк из индекса придется за каждой пойти в таблицу и перепроверить — получается больше работы с диском, чем подряд.
Это связано с MVCC; в 9.2 появились index-only запросы, но и у них, кажется, есть свои ограничения, я не помню деталей.
По-моему, вот этой причиной — проще считать таблицу, чем делать кучу seek-ов по диску — объясняется большинство случаев выбора Seq Scan постгресом.
Может быть ещё забавное. У меня вот недавно была ситуация — я получал несколько сотен тысяч айдишников в скрипте и по 1000 за раз брал их из базы. Получал таймауты (2 секунды у нас в коде прикручено). Отсортировал айдишники перед тем, как брать из них порции — таймауты ушли :-) И это понятно.
Вообще, если планировщик явно тупит, то первое, что стоит сделать — это ANALYZE таблицы. Ещё можно попробовать сбросить статистику планировщика и дать ей накопиться снова — мало ли, характер нагрузки на сервер изменился.
Но перед сбросом — подумать, почему PostgreSQL может себя так вести.
Например, у вас маленькая таблица, она в кеше — её проще перебрать так, действительно.
Или у вас неселективный запрос — тогда тоже проще считать всё и отфильтровать; потому что если постгрес сначала пойдет в индекс — ему после получения списка строк из индекса придется за каждой пойти в таблицу и перепроверить — получается больше работы с диском, чем подряд.
Это связано с MVCC; в 9.2 появились index-only запросы, но и у них, кажется, есть свои ограничения, я не помню деталей.
По-моему, вот этой причиной — проще считать таблицу, чем делать кучу seek-ов по диску — объясняется большинство случаев выбора Seq Scan постгресом.
Может быть ещё забавное. У меня вот недавно была ситуация — я получал несколько сотен тысяч айдишников в скрипте и по 1000 за раз брал их из базы. Получал таймауты (2 секунды у нас в коде прикручено). Отсортировал айдишники перед тем, как брать из них порции — таймауты ушли :-) И это понятно.
ANALYZE это самое первое, что делаю, да.
Заметил, что часто такое поведение наблюдается, когда по этим индексам идет партицирование таблиц.
Заметил, что часто такое поведение наблюдается, когда по этим индексам идет партицирование таблиц.
О! А я заметил, что если у меня партиционирование по времени, и я делаю запрос по интервалу времени, который целиком укладывается в одну партицию, то намного быстрее запрос идет, если делать его напрямую к ней, а не к сводной таблице.
Не помню уже — то ли разы разницы, а то ли и порядок.
Не помню уже — то ли разы разницы, а то ли и порядок.
А вы посмотрите analyze для этого запроса — запрос должен сразу перебрасываться на нужную партицию. А cost для обоих запросов должен совпадать. У меня тоже была подобная бага, индекс как-то криво создался чтоли. Пересоздал индекс — все заработало как нужно.
Да я уже гвоздями прикрутил (да-да, именно так!) выбор напрямую нужной партиции :-)
Красиво будет разобраться, конечно, но оно работает — а более животрепещущих проблем навалом.
Но спасибо, я буду в будущем меньше опасаться партиций.
Красиво будет разобраться, конечно, но оно работает — а более животрепещущих проблем навалом.
Но спасибо, я буду в будущем меньше опасаться партиций.
* В определении партиций точно стоят CHECK на ВСЕХ партициях?
* Интервалы указанные в CHECK точно НЕ пересекаются? Это частая проблема, когда используют BETWEEN и границы автоматически включены в обе соседние таблицы.
Ну и как бонус, вдруг кому-то пригодится: небольшой Partitioning триггер, который создаёт партиции автоматически, если её еще не существует при вставке в мастер таблицу.
* Интервалы указанные в CHECK точно НЕ пересекаются? Это частая проблема, когда используют BETWEEN и границы автоматически включены в обе соседние таблицы.
Ну и как бонус, вдруг кому-то пригодится: небольшой Partitioning триггер, который создаёт партиции автоматически, если её еще не существует при вставке в мастер таблицу.
Если даже pg_hint_planner не помогает, то скорее всего планировщик не тупит, а просто не может то, что вы от него хотите.
Чтобы в части про PostgreSQL можно было что-то понять, нужны версии, определения таблиц, индексов, полные тексты запросов, EXPLAIN (ANALYZE, VERBOSE, BUFFERS) для каждого из запросов. А сейчас пока что только «крик души» )))
Я не готов :-)
Запросы там на несколько сотен символов, непростые. Выводить из этого минимальный повторяющийся случай будет слишком долго, у меня нет времени. Очень много работы.
Мне кажется, суть вполне понятна — вот есть запрос, в нем есть условие по полю intarray, всё работает по индексу (индексу именно по Intarray, именно это поле наиболее селективно), чудесно. Добавляем ещё одно условие на это поле — и кровь кишки :-)
Я не пытаюсь сказать, что тут гарантированно виноват PostgreSQL, я безусловно не понимаю ситуацию до конца, чтобы вот прямо багрепорт пойти написать — но это безусловно было очень странно.
Запросы там на несколько сотен символов, непростые. Выводить из этого минимальный повторяющийся случай будет слишком долго, у меня нет времени. Очень много работы.
Мне кажется, суть вполне понятна — вот есть запрос, в нем есть условие по полю intarray, всё работает по индексу (индексу именно по Intarray, именно это поле наиболее селективно), чудесно. Добавляем ещё одно условие на это поле — и кровь кишки :-)
Я не пытаюсь сказать, что тут гарантированно виноват PostgreSQL, я безусловно не понимаю ситуацию до конца, чтобы вот прямо багрепорт пойти написать — но это безусловно было очень странно.
Про постгрес и intarray надо было ко мне обратиться. Там много есть улучшений и ускорений потенциальных.
Олег, мы были бы очень рады с вами познакомиться и пообщаться :-)
Помнится, в первые полгода жизни сервиса я даже с вами связывался, но не мог толком сформулировать свои мысли/вопросы, и общение не пошло.
Нам на самом деле было бы очень здорово иметь с вами рабочие взаимоотношения, вплоть до платных консультаций.
Кстати, двое из нас и с Федором шапочно знакомы — работали рядом в Mail.Ru :-)
Помнится, в первые полгода жизни сервиса я даже с вами связывался, но не мог толком сформулировать свои мысли/вопросы, и общение не пошло.
Нам на самом деле было бы очень здорово иметь с вами рабочие взаимоотношения, вплоть до платных консультаций.
Кстати, двое из нас и с Федором шапочно знакомы — работали рядом в Mail.Ru :-)
P.S. Где-то на второй трети поста (писал в районе 3 ночи) перестал работать предпросмотр — ну и вообще хабр, потому что 500. Интересно, в чем причина :-)
очевидно накосячили с обновлениями… или просто плановая перезагрузка сервера
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Про Surfingbird, лежащие сайты и странности PostgreSQL