LINUX.ORG.RU

Проблема с PostgreSQL. При использовании LIMIT не используется индекс.

 


0

5

Имеется таблица:

feeds=# \d facets
              Table "public.facets"
    Column    |  Type   |       Modifiers        
--------------+---------+------------------------
 product_id   | bigint  | not null
 warehouse_id | bigint  | not null
 field_id     | bigint  | not null
 value        | text    | not null
 locked       | boolean | not null default false
Indexes:
    "unique_facet" UNIQUE CONSTRAINT, btree (product_id, warehouse_id, field_id)
    "facets_value" gin (value gin_trgm_ops)
Check constraints:
    "facets_value_long_enough" CHECK (value <> ''::text)
    "facets_value_trimmed" CHECK (btrim(value) = value)
Foreign-key constraints:
    "facets_field_id_fkey" FOREIGN KEY (field_id) REFERENCES fields(id) ON DELETE CASCADE
    "facets_product_id_fkey" FOREIGN KEY (product_id) REFERENCES products(id) ON DELETE CASCADE
    "facets_warehouse_id_fkey" FOREIGN KEY (warehouse_id) REFERENCES warehouses(id) ON DELETE CASCADE
feeds=# SELECT DISTINCT facets.product_id FROM facets WHERE facets.value ILIKE '%0731304123538%' ORDER BY facets.product_id offset 0;
 product_id 
------------
    1767628
    1787052
    1787365
    2271634
(4 rows)

Time: 26.715 ms
feeds=# explain SELECT DISTINCT facets.product_id FROM facets WHERE facets.value ILIKE '%0731304123538%' ORDER BY facets.product_id offset 0;
                                         QUERY PLAN                                          
---------------------------------------------------------------------------------------------
 Unique  (cost=9759.46..9770.67 rows=2236 width=8)
   ->  Sort  (cost=9759.46..9765.07 rows=2242 width=8)
         Sort Key: product_id
         ->  Bitmap Heap Scan on facets  (cost=1269.37..9634.69 rows=2242 width=8)
               Recheck Cond: (value ~~* '%0731304123538%'::text)
               ->  Bitmap Index Scan on facets_value  (cost=0.00..1268.81 rows=2242 width=0)
                     Index Cond: (value ~~* '%0731304123538%'::text)
(7 rows)

Time: 0.824 ms

Как видите запрос в данном случае использует index facets_value. Но стоит добавить вконец LIMIT 10:

feeds=# explain SELECT DISTINCT facets.product_id FROM facets WHERE facets.value ILIKE '%0731304123538%' ORDER BY facets.product_id offset 0 limit 10;
                                           QUERY PLAN                                           
------------------------------------------------------------------------------------------------
 Limit  (cost=0.56..8557.31 rows=10 width=8)
   ->  Unique  (cost=0.56..1913289.72 rows=2236 width=8)
         ->  Index Scan using unique_facet on facets  (cost=0.56..1913284.12 rows=2242 width=8)
               Filter: (value ~~* '%0731304123538%'::text)
(4 rows)

Time: 1.523 ms
feeds=# SELECT DISTINCT facets.product_id FROM facets WHERE facets.value ILIKE '%0731304123538%' ORDER BY facets.product_id offset 0 limit 10;
 product_id 
------------
    1767628
    1787052
    1787365
    2271634
(4 rows)

Time: 27863.692 ms

Как вы видите index facets_value не используется. В итоге запрос занимает 27 секунд вместо нескольких миллисекунд как в первом случае.

В чём может быть причина.

Проблема возникает только на удалённом сервере debian PostgreSQL 9.6.4 on x86_64-pc-linux-gnu, compiled by gcc (Debian 6.3.0-18) 6.3.0 20170516, 64-bit

На моём компьютере gentoo PostgreSQL 9.5.7 on x86_64-pc-linux-gnu, compiled by x86_64-pc-linux-gnu-gcc (Gentoo 5.4.0-r3 p1.3, pie-0.6.5) 5.4.0, 64-bit индекс используется в любом случае..

Может быть следует изменить какие то настройки??


забыл добавить что на удалённый сервак бд было закачано с помощью pg_dumpа в SQL file.

iluha16
() автор топика

локально данные в базе и на сервере одни и теже ? У постгреса использование индексов в планировщике очень завязано на сами данные.

anonymous
()
Ответ на: комментарий от anonymous

Ну и еще у тебя версии отличаются постгреса, поставь на сервер ту же самую версию что и локально.

anonymous
()
Ответ на: комментарий от legolegs

Насколько я понимаю - offset может, а вот почему limit - не понятно.

iluha16 может ANALYZE поможет?

AlexKiriukha ★★★★
()
Последнее исправление: AlexKiriukha (всего исправлений: 1)
Ответ на: комментарий от anonymous

вроде как тормозит более свежая версия 9.6.4. может быть там какие то настройки по умолчанию. я толком не знаю как ставить в этом дебиане кое как поставил по инструкции найденной на просторах гугла. как не хочется возиться с этой перестановкой да и интересно вобще выяснить в чём же дело.

iluha16
() автор топика

Объясните мне в чём логика? Ну не хочет с лимит уберу его пусть щитает всё

iluha16
() автор топика

Limit 10 делит финальный кост пропорционально количеству таплов, поэтому с ним индекс скан для постгри кажется более выгодным. Эта долбанная особенность всю плеш выедает, когда объемы табличек начинают быть большими. На старых (9.2, 9.4) работал трюк с подзапросом, `select * from (select * from table where ...) a limit N;`, именно в таком виде, CTE «оптимизировались».

anonymous
()
Ответ на: комментарий от anonymous

Из еще прекрасного. На больших таблицах с пользователями безобидный `select * from users where email = :email limit 1` приводит к фулскану, по той же самой причине. $USER, не используй лимитирование в постгре, когда знаешь верхнюю границу выборки, и тогда волосы будут гладкими и шелковистыми!

anonymous
()
Ответ на: комментарий от anonymous

И таки да, vacuum analyze :table запускался? Так как ты, видимо, заливал дамп недавно, стата косая. Необходимо обновить.

anonymous
()
Ответ на: комментарий от anonymous

VACUUM ANALYZE facets; помогло. А в будущем как будет? Получается эту команду придётся регулярно вводить

iluha16
() автор топика

Покажи дифф между конфигами. Наверняка цены операций разные и оптимизатор сходит с ума.

AnDoR ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.