Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Поиск по составному индексу в WHERE и ORDER BY
|
|||
|---|---|---|---|
|
#18+
Предположим, есть таблица tbl с колонками f и b. Рассмотрим запрос: Код: 1. 2. 3. 4. 5. Если в таблице tbl запросу WHERE удовлетворяют подавляющее большинство записей (поле f - некоторый флаг, значение 1 которого говорит об активности записи, а 0 - о том, что запись архивна), то скорость работы приведенного запроса резко замедляется. Пробовал создавать индексы по f, по b, по совокупности f и b. Ничего не помогает. Удаляем "WHERE f=1" - все начинает работать мгновенно, убираем "ORDER BY b" - то же самое. А вместе - жуткие тормоза (в таблице сотни тысяч записей). EXPLAIN ANALYSE показывает, что вначале он производит фильтрацию по f, а затем - сортировку по b. Естественно, надо делать наоборот: сортировку по b, а уж потом - фильтрацию по f. Если бы PG был достаточно умен, чтобы сообразить использовать составной индекс (f, b) при таком запросе, проблем бы не было. Вопрос - можно ли все же как-то его заставить это сделать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2006, 23:59 |
|
||
|
Поиск по составному индексу в WHERE и ORDER BY
|
|||
|---|---|---|---|
|
#18+
VACUUM ANALYZE выполнялся? Какая версия постгреса? Можно результат EXPLAIN ANALYZE увидеть? По-идее индекс (f,b) должен использоваться. Кстати в версии 8.1 при отключенном enable_bitmapscan план иногда бывает лучше - похоже что оптимизатор действительно тупит и делает bitmap scan вместо index scan там где не нужно. Из-за этого стоимость использования составного индекса оказывается выше чем простого. И если активных записей немного, то не факт, что выгодней скан индекса по b, а затем фильтрация по f - ведь для этого надо все записи просматривать. В этом случае вместо индекса (f, b) выгоднее сделать Код: plaintext ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.07.2006, 04:06 |
|
||
|
Поиск по составному индексу в WHERE и ORDER BY
|
|||
|---|---|---|---|
|
#18+
Сдается мне, ты неправильно понимаешь логику работы сервера. :) Есть определенная последовательность выполнения запроса, и все сервера (в том числе и PostgreSQL) выполняют запросы именно в такой последовательности, ибо это - стандарт. И последовательность такова: 1) Формируется множество данных по таблицам и наборам данных, указанных во фразе FROM. 2) Накладываются ограничения из фразы WHERE на полученной множество. 3) Если указана группировка - производится группировка 4) Если указано условие фильтрации на результат группировки (фраза HAVING) - выполняется фильтрация. 5) Выполняется сортировка полученного итогового множества 6) И только после всего вышесказанного накладываются такие специфические вещи, как LIMIT / TOP N / FIRST N. Поэтому сервер ну никак не может сделать вначале сортировку, а потом фильтрацию результата. Но тебе никто не мешает его обмануть ;): Код: plaintext 1. 2. 3. 4. Правда не факт, что так оно будет работать значительно быстрее - ведь необходимость сортировать выборку по прежднему остается... ----------------------------------------------------------------------------------------------------------------------------------------- З.Ы. Неспешно ищу работу, согласен на переезд в Москву или Питер ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.07.2006, 04:17 |
|
||
|
Поиск по составному индексу в WHERE и ORDER BY
|
|||
|---|---|---|---|
|
#18+
Владимор Конев Правда не факт, что так оно будет работать значительно быстрее - ведь необходимость сортировать выборку по прежднему остается... не поясните следующий результат: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Код: plaintext 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.07.2006, 11:33 |
|
||
|
Поиск по составному индексу в WHERE и ORDER BY
|
|||
|---|---|---|---|
|
#18+
Дмитрий КотеровПробовал создавать индексы по f, по b, по совокупности f и b. Ничего не помогает. EXPLAIN ANALYSE показывает, что вначале он производит фильтрацию по f, а затем - сортировку по b.То есть используется SeqScan? Если старая версия постгреса можно попробовать "ORDER BY f,b" при наличии индекса по совокупности полей (f,b). (Приводите выдачу explain, она легче читается.:) Дмитрий КотеровЕсли бы PG был достаточно умен, чтобы сообразить использовать составной индекс (f, b) при таком запросе, проблем бы не было. Вопрос - можно ли все же как-то его заставить это сделать?На это ума у постгреса определенно должно хватить. :) Владимор КоневЕсть определенная последовательность выполнения запроса, и все сервера (в том числе и PostgreSQL) выполняют запросы именно в такой последовательности, ибо это - стандарт.Надо смотреть на планы запросов, чтобы узнать какие именно шаги и в какой последовательности выполняются. Владимор Конев1) Формируется множество данных по таблицам и наборам данных, указанных во фразе FROM.Скорее надо рассматривать обработку как поточную. "Множество данных формируется" лишь когда в плане присутствует что-то типа Materialize, Hash, Sort. Владимор Конев2) Накладываются ограничения из фразы WHERE на полученной множество.Ограничения могут накладываться посредством Filter, IndexCond,.. - это разные вещи в плане эффективности. Здесь рассуждать надо более точными понятиями этапов выполнения запроса, которые показывает explain. Владимор Конев Код: plaintext Владимор Коневведь необходимость сортировать выборку по прежднему остается...При выполнении через IndexScan сортировка может исчезнуть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.07.2006, 12:28 |
|
||
|
Поиск по составному индексу в WHERE и ORDER BY
|
|||
|---|---|---|---|
|
#18+
4321не поясните следующий результат: ... т.е. кажется постгресу иногда удается наложить лимит не затрудняясь получением всего, что возвращает WHERE ? или я что-то не так понимаю?Сортировки нет потому, что условия сортировки (порядок полей и направление упорядочивания) совпадают с оными в индексе. Поэтому PostgreSQL выбрал индекс скан и как заметил LeXa NalBat LeXa NalBat При выполнении через IndexScan сортировка может исчезнуть. Условие WHERE было опущено и заменено на все тот же индекс скан, так как само условие фильтрации данных опять же совпадает с определением индекса. В итоге получили в чистом виде индекс скан + наложение ограничения на выборку посредством LIMIT, как вполне достаточными для получения правильного результата (индекс еще в добавок ко всему и уникальный). По-моему так, но могу и ошибаться - я же с PostgreSQL не работаю... Если где-то ошибаюсь - поправьте, буду рад. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.07.2006, 13:34 |
|
||
|
Поиск по составному индексу в WHERE и ORDER BY
|
|||
|---|---|---|---|
|
#18+
Владимор КоневУсловие WHERE было опущено и заменено на все тот же индекс сканНельзя смешивать 1) конструкции sql-запроса (where), которые sql-сервер обязан выполнить и 2) план выполнения запроса (индекс скан), на который вы не можете гарантированно влиять. Владимор Коневтак как само условие фильтрации данных опять же совпадает с определением индекса.В вашем примере индекс был безусловным. Паршиал-индекс where f=1 наверное не должен использоваться в запросе без where f=1. Владимор КоневВ итоге получили в чистом виде индекс скан + наложение ограничения на выборку посредством LIMIT, как вполне достаточными для получения правильного результата (индекс еще в добавок ко всему и уникальный). Код: plaintext 1. 2. 3. 4. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.07.2006, 14:32 |
|
||
|
Поиск по составному индексу в WHERE и ORDER BY
|
|||
|---|---|---|---|
|
#18+
LeXa NalBat Владимор КоневУсловие WHERE было опущено и заменено на все тот же индекс сканНельзя смешивать 1) конструкции sql-запроса (where), которые sql-сервер обязан выполнить и 2) план выполнения запроса (индекс скан), на который вы не можете гарантированно влиять. Владимор Коневтак как само условие фильтрации данных опять же совпадает с определением индекса.В вашем примере индекс был безусловным. Паршиал-индекс where f=1 наверное не должен использоваться в запросе без where f=1. Владимор КоневВ итоге получили в чистом виде индекс скан + наложение ограничения на выборку посредством LIMIT, как вполне достаточными для получения правильного результата (индекс еще в добавок ко всему и уникальный). Код: plaintext 1. 2. 3. 4. Мой пост был всего лишь ответом на вопрос от 4321 , разъясняющим поведение сервера в отдельно взятой конкретной ситуации, которую продемонстрировал 4321. Не более того. Всё остальное - лишь твои домыслы и додумки к моим словам. Ибо моё мнение по прежднему остается таким, как я его высказал в своем ответе автору топика . Единственное, что в ситуации, опиаснной 4321, этапы по наложению условий фильтрации + сортировка результата были выполнены ПРЕДВАРИТЕЛЬНО, НА МОМЕНТ СОЗДАНИЯ ИНДЕКСА. И сервер просто облегчил себе работу, заменив в эквивалентной ситуации часть шагов на результат предварительно проделанной работы (то есть заменив шаги 2 и 5 на скан индекса, так как эти самые 2-й и 5-й шаг УЖЕ БЫЛИ ВЫПОЛНЕНЫ сервером при создании соответствующего индекса) Вот такого: Владимор КоневВ итоге получили в чистом виде индекс скан + наложение ограничения на выборку посредством LIMIT, как вполне достаточными для получения правильного результата (индекс еще в добавок ко всему и уникальный). Код: plaintext 1. 2. 3. 4. Во всем том, что ты сказал есть лишь одно верное (но вплоне опровержимое) высказывание: LeXa NalBatРезультат будет неправильным, если в таблице менее 500 строк с f=1 и хотя бы одна строка с f=0. НО!!! Никто не мешает тебе обмануть сервер дважды: вначале выполнить запрос в том виде что я написал, получить результат, а потом в обрамляющем (внешнем) запросе наложить дополнительно условие WHERE f = 1. Таким образом запрос примет вид: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2006, 05:12 |
|
||
|
Поиск по составному индексу в WHERE и ORDER BY
|
|||
|---|---|---|---|
|
#18+
Владимор Конев Еще вопросы имеются???да их и сразу не было. попросту указали на вашу неточность в формулировке: авторЕсть определенная последовательность выполнения запроса, и все сервера (в том числе и PostgreSQL) выполняют запросы именно в такой последовательности, ибо это - стандарт. +многобуковвы забрали многобуков взад (или же начали выкручиваться - мол "тута рыбку заворачивали" и т.п. - что, в сущности, рояля не играет - это проблемы _вашей_ готовности отвечать за _ваши_ многобуков, а не чьей-то "(не)внимательности" ). Т.е. в итоге все всем ястно, а кто и как хочет вихлядеть в своих собственных глазах - дело десятое. надеюсь вопросов нет? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2006, 11:02 |
|
||
|
Поиск по составному индексу в WHERE и ORDER BY
|
|||
|---|---|---|---|
|
#18+
4321надеюсь вопросов нет?Лично у меня 4321да их и сразу не было(с) ----------------------------------------------------------------------------------------------------------------------------------------- З.Ы. Неспешно ищу работу, согласен на переезд в Москву или Питер ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2006, 11:08 |
|
||
|
Поиск по составному индексу в WHERE и ORDER BY
|
|||
|---|---|---|---|
|
#18+
Владимор КоневЧего-то ты вообще все в кучу замешал... :)Я подумал, что ваши слова "Условие WHERE было опущено и заменено на все тот же индекс скан, так как само условие фильтрации данных опять же совпадает с определением индекса. В итоге получили в чистом виде индекс скан + наложение ограничения на выборку посредством LIMIT, как вполне достаточными для получения правильного результата (индекс еще в добавок ко всему и уникальный)" относятся к предложенному вами запросу с "-- WHERE f=1 Условие фильтрации нафиг не нужно". Владимор КоневНикто не мешает тебе обмануть сервер дважды: вначале выполнить запрос в том виде что я написал, получить результат, а потом в обрамляющем (внешнем) запросе наложить дополнительно условие WHERE f = 1. Таким образом запрос примет вид: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2006, 12:33 |
|
||
|
Поиск по составному индексу в WHERE и ORDER BY
|
|||
|---|---|---|---|
|
#18+
LeXa NalBatЯ подумал, что ваши слова ... относятся к предложенному вами запросу с "-- WHERE f=1 Условие фильтрации нафиг не нужно".Я так и понял ;) LeXa NalBatТакой запрос может выдать неправильный результат, потому что во внешнем подзапросе отсутствует "order by".А зачем он там? Только для формальности? Ну добавь, лишним не будет... Хотя, опять же , не зная особенностей поведения PostgreSQL при выполнении запросов из derived-таблиц, лучше таки поставить ORDER BY во внешнем запросе, а то вдруг серверу вздумается пересортировать данные перед тем, как он их начнет обрабатывать внешним запросом... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2006, 12:42 |
|
||
|
Поиск по составному индексу в WHERE и ORDER BY
|
|||
|---|---|---|---|
|
#18+
Владимор Конев LeXa NalBatТакой запрос может выдать неправильный результат, потому что во внешнем подзапросе отсутствует "order by".А зачем он там? Только для формальности? Хотя, опять же , не зная особенностей поведения PostgreSQL при выполнении запросов из derived-таблиц, лучше таки поставить ORDER BY во внешнем запросе, а то вдруг серверу вздумается пересортировать данные перед тем, как он их начнет обрабатывать внешним запросом...Вот вот, именно для этого. И даже зная особенности сегодняшнего поведения постгреса нельзя гарантировать, что в будущей версии он не захочет сделать какой-нибудь BitMapFilter или SuperPuperAction, при котором потеряется сортировка. Также существуют другие СУБД, в большинстве которых этот правильный запрос с "order by" будет работать одинаково верно. Владимор КоневНу добавь, лишним не будет...Добавил. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2006, 13:21 |
|
||
|
Поиск по составному индексу в WHERE и ORDER BY
|
|||
|---|---|---|---|
|
#18+
LeXa NalBat Однако в постгресе нельзя создать индекс по (f desc,b) без дополнительных усилий. (есть способ задать (создав его явно) свой способ сравнения в индексе, правда я не знаю способа указать этот способ сравнения в ORDER BY) LeXa NalBatпоэтому к выбору плана IndexScan без сортировки (лишь это дает кардинальный выигрыш в производительности) такой запрос не приведет. :(для типов, для которых определена инверсия (-f), возможно таки извратиться (с одноверменной заменой f desc на (-f) и в ORDER BY и в индексе), но с оговорками о Null-абельности поля. Посему я взял -1 за True, и при фильтрации только активных записей (или всех) имею пользование составным индексом (есть и не условный индекс) в наиболее часто встречающихся конструкциях. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2006, 13:38 |
|
||
|
Поиск по составному индексу в WHERE и ORDER BY
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. В принципе, да, это решение. Спасибо. Однако все же вопрос остается в силе: неужели Постгрес не может самостоятельно проделать такую трансформацию над запросом Код: plaintext 1. Правда, я не пробовал еще делать VACUUM ANALYZE (реальная база слишком большая, минут 30 будет выполняться), но - обязательно попробую. Потом напишу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.08.2006, 09:42 |
|
||
|
Поиск по составному индексу в WHERE и ORDER BY
|
|||
|---|---|---|---|
|
#18+
Дмитрий КотеровОднако все же вопрос остается в силе: неужели Постгрес не может самостоятельно проделать такую трансформацию над запросом Код: plaintext ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.08.2006, 11:08 |
|
||
|
|

start [/forum/topic.php?fid=53&msg=33884493&tid=2006179]: |
0ms |
get settings: |
10ms |
get forum list: |
17ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
90ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
73ms |
get tp. blocked users: |
2ms |
| others: | 268ms |
| total: | 483ms |

| 0 / 0 |
