|
Как заставить Postgres использовать определенный индекс
|
|||
---|---|---|---|
#18+
Есть запрос Код: sql 1. 2. 3. 4. 5. 6.
В базе есть индекс по полю Field1 и составной индекс по 2 полям (Field2 и Field3). Если в запросе указать ограничение LIMIT, то используется индекс по полю Field1 и потребляется много ресурсов. Если в запросе убрать ограничение LIMIT, то используется составной индекс (Field2 и Field3) ресурсов тратиться в 2 раза меньше, но время выполнения запроса в несколько раз больше. Вопрос можно ли в запросе оставить LIMIT 100 и обязать Postgres использовать составной индекс? ... |
|||
:
Нравится:
Не нравится:
|
|||
06.06.2018, 16:23 |
|
Как заставить Postgres использовать определенный индекс
|
|||
---|---|---|---|
#18+
Например, если изменить запрос на Код: sql 1. 2. 3. 4. 5. 6.
то используется составной индекс (Field2 и Field3), но время выполнения также увеличивается в несколько раз ... |
|||
:
Нравится:
Не нравится:
|
|||
06.06.2018, 17:27 |
|
Как заставить Postgres использовать определенный индекс
|
|||
---|---|---|---|
#18+
polin11, Что если добавить в запрос order by и поля по которым надо использовать индекс? ... |
|||
:
Нравится:
Не нравится:
|
|||
06.06.2018, 17:30 |
|
Как заставить Postgres использовать определенный индекс
|
|||
---|---|---|---|
#18+
Если добавить ORDER BY и дополнительные поля: Код: sql 1. 2. 3. 4. 5. 6. 7.
то используется составной индекс, но время выполнения в несколько раз больше ... |
|||
:
Нравится:
Не нравится:
|
|||
06.06.2018, 17:41 |
|
Как заставить Postgres использовать определенный индекс
|
|||
---|---|---|---|
#18+
даже если проставить LIMIT 200000, то используется составной индекс ... |
|||
:
Нравится:
Не нравится:
|
|||
06.06.2018, 17:42 |
|
Как заставить Postgres использовать определенный индекс
|
|||
---|---|---|---|
#18+
polin11, Похоже что его оптимизатор видит order by по индексу для выполнения distinct, но рвется на limit. Вот такой explain select field1 from ( select distinct field1 from ttt where field1='val1' and field2 like 'val2%' order by field1) as tmp limit 100; по идее должен отдать первые distinct сортированные по индексу но второй отсечь по лимиту 100. explain показывает малые числа. Данных для проверки не имею, только схему. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.06.2018, 18:24 |
|
Как заставить Postgres использовать определенный индекс
|
|||
---|---|---|---|
#18+
К сожалению, используется индекс только по полю Field1. В данном случае, видимо, стоит выбор между быстродействием и ресурсоемкостью ... |
|||
:
Нравится:
Не нравится:
|
|||
06.06.2018, 22:53 |
|
Как заставить Postgres использовать определенный индекс
|
|||
---|---|---|---|
#18+
polin11К сожалению, используется индекс только по полю Field1. В данном случае, видимо, стоит выбор между быстродействием и ресурсоемкостью Если вам нужно быстродействие этого запроса - сделайте правильный индекс под этот запрос вида: create index someindexname on "Table"("Field3", "Field2" text_pattern_ops); (если "Field2" varchar тогда вместо text_pattern_ops сделать varchar_pattern_ops) -- Maxim Boguk dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
06.06.2018, 23:16 |
|
Как заставить Postgres использовать определенный индекс
|
|||
---|---|---|---|
#18+
К сожалению даже такой сокращенный запрос Код: sql 1. 2. 3. 4.
Планировщик использует индекс по полю Field1, а не индекс по полю Field2. Fileld2 поле типа text, индекс добавлен с классом операторов text_pattern_ops. Для примера , если изменить запрос Код: sql 1. 2. 3. 4.
или Код: sql 1. 2. 3.
даже такой запрос, с другим фильтром "Field2" = 'val1' Код: sql 1. 2. 3. 4.
То во всех случаях используется индекс по полю Field2, но в этих случаях время выполнения запроса слишком большое ... |
|||
:
Нравится:
Не нравится:
|
|||
07.06.2018, 01:47 |
|
Как заставить Postgres использовать определенный индекс
|
|||
---|---|---|---|
#18+
Maxim Bogukpolin11К сожалению, используется индекс только по полю Field1. В данном случае, видимо, стоит выбор между быстродействием и ресурсоемкостью Если вам нужно быстродействие этого запроса - сделайте правильный индекс под этот запрос вида: create index someindexname on "Table"("Field3", "Field2" text_pattern_ops); (если "Field2" varchar тогда вместо text_pattern_ops сделать varchar_pattern_ops) -- Maxim Boguk dataegret.ru это тот случай, когда бартунов сильно под.... постгресу с его использованием унешних локалей. наврал. достаточно луз-индекскана по полю 1 . с экзистсом по лайку на поле 2 по составному с лидирующим 1-м и опсами на 2--м. если кардинальности подходящие. наверное можете пополнить вашу коллекцию трюков т.е. бартунов неуиноватый. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.06.2018, 10:53 |
|
Как заставить Postgres использовать определенный индекс
|
|||
---|---|---|---|
#18+
qwwqMaxim Bogukпропущено... Если вам нужно быстродействие этого запроса - сделайте правильный индекс под этот запрос вида: create index someindexname on "Table"("Field3", "Field2" text_pattern_ops); (если "Field2" varchar тогда вместо text_pattern_ops сделать varchar_pattern_ops) -- Maxim Boguk dataegret.ru это тот случай, когда бартунов сильно под.... постгресу с его использованием унешних локалей. наврал. достаточно луз-индекскана по полю 1 . с экзистсом по лайку на поле 2 по составному с лидирующим 1-м и опсами на 2--м. если кардинальности подходящие. наверное можете пополнить вашу коллекцию трюков т.е. бартунов неуиноватый. Из описанного выше, только понял, что ген. дир. Postgres Professional Бартунов не виновен. Ваш совет по структуре индексов не смог интерпретировать. Для запроса Код: sql 1. 2. 3. 4.
Поле Field1 тип bigint, по нему есть индекс, при выполнении этого запроса он и используется ( Index Scan using "iTable-Field1" on "Table" ). Поле Filed2 типа text, поле Fileld3 типа bigint. Есть индекс SearchFields составной состоит из поля Field2 с типом операторов text_pattern_ops, и поля Field3. Если убрать из запроса LIMIT 100, то используется Bitmap Index Scan on "iTable-SearchFields". Ресурсов тратиться меньше, но времени больше. Поясните подробно, что нужно сделать с индексами, по Вашему мнению? ... |
|||
:
Нравится:
Не нравится:
|
|||
09.06.2018, 17:20 |
|
Как заставить Postgres использовать определенный индекс
|
|||
---|---|---|---|
#18+
polin11, "мэньше" "болше" -- ви што, штаны меряете ? план запросав рисуйте давайте с цифиркой -- скока менше , скока больше. а про реализацию луз-индекс-сканов для дистинктов тут уже много где понаписано. поищите. loose http://www.sql.ru/forum/actualsearch.aspx?search=loose index scan&sin=0&bid=7&a=&ma=0&dt=-1&s=1&so=1 скушно всё одно и то же по 100-му разу накручивать. опять же в статистику и соотношения кардинальностей упираемся. и да , я со слепу не всё увидел, для луза видимо вам потребуется индекс (Ф3,Ф1,Ф2 с опсами) и прямые руки как проваливаться на второй уровень в рекурсии луза (при редком первом или константе как у вас) я где-то недавно писал. но так ли оно по мощностям -- надо ваш случай смотреть . а будет ли пресловутый опс упираться отсутствием отношения порядка (недоступностью вернее) выведенного наружу -- надо смотреть по мере реализации . тогда и решим -- увиновин рафик или неувиновин в данном конкретном. если писать сложного луза руками не хотите -- сделайте или (Ф3,Ф2 с опсами) как кто-то выше подбросил. именно в таком порядке. или простой луз по Ф1 с речеком условия. (и помянутый индекс все равно не помешает) а вообще без планов и цифр -- это гадание какое-то ... |
|||
:
Нравится:
Не нравится:
|
|||
09.06.2018, 23:36 |
|
Как заставить Postgres использовать определенный индекс
|
|||
---|---|---|---|
#18+
polin11, Для начала показать что дают 3 запроса: 1)SELECT count(*) FROM "Table"; 2)SELECT count(*) FROM "Table" WHERE "Field2" LIKE 'val1%' AND "Field3" ='val2' 3)SELECT count(DISTINCT "Field1") FROM "Table" WHERE "Field2" LIKE 'val1%' AND "Field3" ='val2' А там подумаем. Все советы исходили из того что WHERE условие у вас высокоселективное (т.е. под него попадает условно 0.1% таблицы или меньше). Если это не так - то задача: а)вообще странная очень б)не имеет эффективного решения с помощью индексов без полной переделки запроса -- Maxim Boguk dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
10.06.2018, 00:16 |
|
Как заставить Postgres использовать определенный индекс
|
|||
---|---|---|---|
#18+
Maxim Boguk, из того, что при лимите "запрос считается быстро" -- селективность самого Ф1 хороша. и/или порядок скорее всего далёк от кластерного вдоль оного. "ресурсов больше" --WTF -- скорее всего параллел запускается. (так отключить его перед запросом и делов) раз Ф3 упорно суётся последним -- оно малоселективное, и ,согласно дебильному поверию, индекс с него лучше не начинать (алфавитный указатель не должен начинаться с буквы раздела . ага. д.б.) даже булево Ф3 перед Ф1 снизит расходы по задаче вдвое (при пополамном распределении) . а после -- будет болтаться как г-но в проруби, разве что для иос пригодится. полюбасу индекс (Ф3,Ф1,Ф2опс) для данной задачи с лимитом -- оптимален. даже если луза не реализовывать. (для речека тоже) ... |
|||
:
Нравится:
Не нравится:
|
|||
10.06.2018, 10:54 |
|
Как заставить Postgres использовать определенный индекс
|
|||
---|---|---|---|
#18+
Интересное наблюдение: 1) Если записей удовлетворяющих условию "Field2" LIKE 'val1%' AND "Field3" ='val2' меньше 3000, то используется составной индекс, если больше, то индекс по полю Field1. 2) Если из запроса убрать DISTINCT и записей удовлетворяющих условию "Field2" LIKE 'val1%' AND "Field3" ='val2' меньше 1 млн., то также используется составной индекс. 3) Если из запроса убрать DISTINCT и записей удовлетворяющих условию больше 1 млн., то вообще используется Seq scan ... |
|||
:
Нравится:
Не нравится:
|
|||
13.06.2018, 10:53 |
|
Как заставить Postgres использовать определенный индекс
|
|||
---|---|---|---|
#18+
polin11Интересное наблюдение: 1) Если записей удовлетворяющих условию "Field2" LIKE 'val1%' AND "Field3" ='val2' меньше 3000, то используется составной индекс, если больше, то индекс по полю Field1. 2) Если из запроса убрать DISTINCT и записей удовлетворяющих условию "Field2" LIKE 'val1%' AND "Field3" ='val2' меньше 1 млн., то также используется составной индекс. 3) Если из запроса убрать DISTINCT и записей удовлетворяющих условию больше 1 млн., то вообще используется Seq scan цифры где ? умеет ли дон експлейн аналайз ? или вы так, погулять пришли правильно ли я понимваю, что делать индексы дону не доверяют ? ... |
|||
:
Нравится:
Не нравится:
|
|||
13.06.2018, 11:12 |
|
Как заставить Postgres использовать определенный индекс
|
|||
---|---|---|---|
#18+
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
Не устаивает Shared hit memory 2.1Gb ... |
|||
:
Нравится:
Не нравится:
|
|||
13.06.2018, 12:05 |
|
Как заставить Postgres использовать определенный индекс
|
|||
---|---|---|---|
#18+
Maxim Bogukpolin11, Для начала показать что дают 3 запроса: 1)SELECT count(*) FROM "Table"; 2)SELECT count(*) FROM "Table" WHERE "Field2" LIKE 'val1%' AND "Field3" ='val2' 3)SELECT count(DISTINCT "Field1") FROM "Table" WHERE "Field2" LIKE 'val1%' AND "Field3" ='val2' А там подумаем. Все советы исходили из того что WHERE условие у вас высокоселективное (т.е. под него попадает условно 0.1% таблицы или меньше). Если это не так - то задача: а)вообще странная очень б)не имеет эффективного решения с помощью индексов без полной переделки запроса -- Maxim Boguk dataegret.ru SELECT count(*) FROM "Table" 15910261 SELECT count(*) FROM "Table" WHERE "Field2" LIKE 'val1%' AND "Field3" ='val2' 1103549 SELECT count(DISTINCT "Field1") FROM "Table" WHERE "Field2" LIKE 'val1%' AND "Field3" ='val2' 1029457 ... |
|||
:
Нравится:
Не нравится:
|
|||
14.06.2018, 00:27 |
|
Как заставить Postgres использовать определенный индекс
|
|||
---|---|---|---|
#18+
qwwqMaxim Boguk, из того, что при лимите "запрос считается быстро" -- селективность самого Ф1 хороша. и/или порядок скорее всего далёк от кластерного вдоль оного. "ресурсов больше" --WTF -- скорее всего параллел запускается. (так отключить его перед запросом и делов) раз Ф3 упорно суётся последним -- оно малоселективное, и ,согласно дебильному поверию, индекс с него лучше не начинать (алфавитный указатель не должен начинаться с буквы раздела . ага. д.б.) даже булево Ф3 перед Ф1 снизит расходы по задаче вдвое (при пополамном распределении) . а после -- будет болтаться как г-но в проруби, разве что для иос пригодится. полюбасу индекс (Ф3,Ф1,Ф2опс) для данной задачи с лимитом -- оптимален. даже если луза не реализовывать. (для речека тоже) Сделал индекс (Field3,Field1,Field2 ops), ситуация аналогичная при запросе Код: sql 1. 2. 3. 4. 5. 6.
используется индекс по Field1, если уберу LIMIT 100, используется вновь созданный индекс (Field3,Field1,Field2 ops) ... |
|||
:
Нравится:
Не нравится:
|
|||
14.06.2018, 00:31 |
|
Как заставить Postgres использовать определенный индекс
|
|||
---|---|---|---|
#18+
polin11SELECT count(*) FROM "Table" 15910261 SELECT count(*) FROM "Table" WHERE "Field2" LIKE 'val1%' AND "Field3" ='val2' 1103549 SELECT count(DISTINCT "Field1") FROM "Table" WHERE "Field2" LIKE 'val1%' AND "Field3" ='val2' 1029457 Таки я не понял чего вы хотите при таком раскладе. Этот запрос база не может подсчитать быстро никаким внятным образом. Это как раз про: Если это не так - то задача: а)вообще странная очень б)не имеет эффективного решения с помощью индексов без полной переделки запроса Хотите быстро подобный запрос - делайте индекс только по (Field3, Field1) и используйте loose index scan технику 100 раз описанную на этом форуме. В 101 раз я ее писать не буду потому что лень. PS: использование LIMIT N без ORDER BY мягко говоря еще один показатель что вы не очень понимаете чего вам надо именно от базы. PPS: если вы считаете что база может используя индексы этот запрос подсчитать быстро - объясните какой алгоритм она должна использовать для этого. -- Maxim Boguk dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
14.06.2018, 00:43 |
|
Как заставить Postgres использовать определенный индекс
|
|||
---|---|---|---|
#18+
Maxim Boguk, 1. я ошибся -- по числу хитов вероятнее всего табличка почти кластеризована по Ф1. 2. его изначальных индексов (и возможно цтид) видимо достаточно для луза . (не хватает данных о мощности самого Ф1). и я таки накидал луз для кейса г-на безручко: data Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
QRY Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22.
explain Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36.
... |
|||
:
Нравится:
Не нравится:
|
|||
14.06.2018, 11:44 |
|
Как заставить Postgres использовать определенный индекс
|
|||
---|---|---|---|
#18+
qwwq, Хочу в начале, выразить Вам благодарность, что тратите личное время на мою проблему и подробно описываете Ваши действия. Спасибо большое!!! Сделал как вы сказали, немного модифицировал ваш запрос Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
Создал индекс CREATE INDEX ON table_ (field3,field1,field2 text_pattern_ops); Все равно планировщик не использует этот индекс, берет индекс по Field1 Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33.
Вот если удалить индекс по Field1, то используется созданный индекс и запрос использует намного меньше ресурсов: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34.
... |
|||
:
Нравится:
Не нравится:
|
|||
14.06.2018, 13:39 |
|
Как заставить Postgres использовать определенный индекс
|
|||
---|---|---|---|
#18+
polin11, 1. не понял -- нахера у вас в выводе стоит дистинкт и ордер бай. они самим рекурсивным цте обеспечиваются. и 2. -- то, что этот шайтан-арба* (пресловутый планировщик пж) по мозговитости планера не ушел от кирпича тупого твёрдого -- не новость. есть целая наука, как совместить разные индексы не снося их. например сделать один из 2-х функциональным, и дурить грёбаный планировщик грёбаного пж. * пс. радует, что в том же оракле года 4 назад я видел рукопашный луз--индекскан. т.е. тут везде на математиксах сэкономили. даже жадный ларри. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.06.2018, 14:58 |
|
Как заставить Postgres использовать определенный индекс
|
|||
---|---|---|---|
#18+
qwwqpolin11, 1. не понял -- нахера у вас в выводе стоит дистинкт и ордер бай. они самим рекурсивным цте обеспечиваются. Да, дистинкт и ордер бай не нужны. Буду думать как совместить индексы, так сказать, перефразируя Пушкина в одну телегу впрячь коня и трепетную лань. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.06.2018, 15:47 |
|
Как заставить Postgres использовать определенный индекс
|
|||
---|---|---|---|
#18+
polin11qwwqpolin11, 1. не понял -- нахера у вас в выводе стоит дистинкт и ордер бай. они самим рекурсивным цте обеспечиваются. Да, дистинкт и ордер бай не нужны. Буду думать как совместить индексы, так сказать, перефразируя Пушкина в одну телегу впрячь коня и трепетную лань. попробуйте вместо CREATE INDEX ON table_ (field3,field1,field2 text_pattern_ops); сделать CREATE INDEX ON table_ (field3,field1); и посмотреть будет ли такой индекс использоваться автоматически. Если нет то можно как уже написали сделать функциональный индекс и запрос под него переписать но это конечно криво. -- Maxim Boguk dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
14.06.2018, 16:56 |
|
|
start [/forum/search_topic.php?author=Tommy+Slash&author_mode=last_posts&do_search=1]: |
0ms |
get settings: |
9ms |
get forum list: |
14ms |
get settings: |
8ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
48ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
62ms |
get tp. blocked users: |
1ms |
others: | 1421ms |
total: | 1599ms |
0 / 0 |