Огромная разница во времени процесса в зависимости от небольшой разницы параметров запроса - PullRequest
0 голосов
/ 29 мая 2018

У меня есть две модели, PartMaster и Location, с отношением один ко многим.Я должен выполнить поиск по полю part_masters.combo и location.ubicacion, используя левое объединение двух таблиц.

Моя проблема заключается в том, что одно и то же время обработки запроса абсолютно отличается в зависимости от того, как параметрызапрос есть.

Этот запрос имеет время выполнения около 450 мс .

План запроса - это

план для запросадля 'P0'

SELECT DISTINCT "part_masters".* FROM "part_masters" LEFT OUTER JOIN 
"locations" ON "locations"."sap_cod" = "part_masters"."sap_cod" WHERE 
(unaccent(locations.ubicacion) ILIKE unaccent('%P0%')) AND 
(unaccent(part_masters.combo) ILIKE unaccent('%junta%')) AND 
(unaccent(part_masters.combo) ILIKE unaccent('%torica%')) ORDER BY 
"part_masters"."sap_cod" ASC

И этот другой запрос, просто изменив 'P0' на 'P01' как параметр запроса location.ubicacion, чтобы выполнить 38 секунд , чтобы выполнить,я перехитрил большую часть времени.

план для запроса, ищущего 'P01'

SELECT DISTINCT "part_masters".* FROM "part_masters" LEFT OUTER JOIN 
"locations" ON "locations"."sap_cod" = "part_masters"."sap_cod" WHERE 
(unaccent(locations.ubicacion) ILIKE unaccent('%P01%')) AND 
(unaccent(part_masters.combo) ILIKE unaccent('%junta%')) AND 
(unaccent(part_masters.combo) ILIKE unaccent('%torica%')) ORDER BY 
"part_masters"."sap_cod" ASC

АНАЛИЗ ВЫХОДА:

Unique  (cost=3880.72..3880.77 rows=1 width=242) (actual 
time=39902.298..39902.305 rows=8 loops=1)
->  Sort  (cost=3880.72..3880.73 rows=1 width=242) (actual 
time=39902.297..39902.297 rows=8 loops=1)
    Sort Key: part_masters.sap_cod, part_masters.id, 
part_masters.descripcion_maestro, part_masters.ref_fabricante, 
part_masters.fabricante, part_masters.stock, part_masters.precio_medio, 
part_masters.planta_cod, part_masters.planta_nombre, 
part_masters.unidad_medida, part_masters.grupo_compras, 
part_masters.created_at, part_masters.updated_at, 
part_masters.combinada_maestro, part_masters.precio_estandar, 
part_masters.fabricante_nombre, part_masters.combo
    Sort Method: quicksort  Memory: 29kB
    ->  Nested Loop  (cost=0.00..3880.71 rows=1 width=242) (actual 
time=10393.015..39902.250 rows=8 loops=1)
          Join Filter: ((part_masters.sap_cod)::text = 
(locations.sap_cod)::text)
          Rows Removed by Join Filter: 438318
          ->  Seq Scan on part_masters  (cost=0.00..2451.75 rows=1 
 width=242) (actual time=2.135..315.211 rows=262 loops=1)
                Filter: ((unaccent(combo) ~~* unaccent('%junta%'::text)) AND 
 (unaccent(combo) ~~* unaccent('%torica%'::text)))
                Rows Removed by Filter: 38408
          ->  Seq Scan on locations  (cost=0.00..1409.24 rows=1578 width=5) 
 (actual time=0.107..148.671 rows=1673 loops=262)
                Filter: (unaccent((ubicacion)::text) ~~* 
 unaccent('%P01%'::text))
                Rows Removed by Filter: 37586
 Total runtime: 39902.358 ms

У меня есть этот индекс в комбо,не используется.

part_masters_on_combo_idx UNUSED (индекс триграммы)

Нет никакого индекса для location.ubicacion.

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

1 Ответ

0 голосов
/ 29 мая 2018

Вам нужны индексы, чтобы PostgreSQL мог ускорить запрос и рассчитать более точные оценки:

CREATE INDEX ON part_masters (lower(unaccent(combo)) text_pattern_ops);
CREATE INDEX ON locations (lower(unaccent(ubicacion)) text_pattern_ops);

Затем запустите ANALYZE для обеих таблиц.

Кроме того, вам придетсяперепишите три условия:

unaccent(part_masters.combo) ILIKE unaccent('%junta%')

следующим образом:

lower(unaccent(part_masters.combo)) LIKE lower(unaccent('%junta%'))

Это должно значительно повысить производительность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...