У меня есть представление SQL (CREATE OR REPLACE VIEW table_view AS ...
), которое имеет 20 столбцов со смесью текстовых, целочисленных, логических и целочисленных полей массива.Всего существует девять столбцов, которые являются целочисленными массивами.
Это представление работает очень хорошо в подавляющем большинстве случаев.Однако, когда в массиве целых чисел появляется строка с ~ 50 полными значениями, запрос замедляется до сканирования.Эти столбцы не запрашиваются, они просто являются частью набора результатов, но величина запроса увеличивается от ~ 250 мс до ~ 7 с, если возвращаются какие-либо строки, содержащие большое количество целочисленных значений массива.
Вот пример запроса:
SELECT
"table_view"."id", -- integer
"table_view"."start", -- date with tz
"table_view"."end", -- date with tz
"table_view"."a_id", -- integer
"table_view"."c_id", -- integer
"table_view"."generator_id", -- integer
"table_view"."ci_id", -- integer
"table_view"."kind", -- integer
"table_view"."hidden", -- boolean
"table_view"."is_done", -- integer
"table_view"."title", -- text
"table_view"."c_type", -- integer
"table_view"."ci_title", -- integer
"table_view"."status", -- text
"table_view"."cs", -- integer array
"table_view"."cts", -- integer array
"table_view"."ts", -- integer array
"table_view"."tas", -- integer array
"table_view"."bs", -- integer array
"table_view"."ms", -- integer array
"table_view"."pcs", -- integer array
"table_view"."pts", -- integer array
"table_view"."ks" -- integer array
FROM
"table_view"
WHERE (
"table_view"."a_id" = 3289
AND (
"table_view"."cs" && ARRAY[28890, 21166, 28891, 29581, 29583, 22378, 22380, 22733, 28924, 28925, 28926, 28927, 28478, 41014]::integer[]
OR "table_view"."ms" && ARRAY[11125]::integer[]
) AND NOT (
"table_view"."hidden" = true
AND NOT (
"table_view"."ms" && ARRAY[11125]::integer[]
)
) AND "table_view"."end" >= '2019-02-03T00:00:00+00:00'::timestamptz
AND "table_view"."start" < '2019-04-15T00:00:00+00:00'::timestamptz
);
Если ни одна из строк не имеет суммы значений целочисленного массива ~> 50, время запроса составляет от ~ 50 мс до 250 мс.
Time: 50.417 ms
Однако, если одна или несколько строк имеют сумму значений целочисленного массива <~ 50, время запроса составляет от ~ 6,5 с до 7 с. </p>
Time: 6737.154 ms
Я запутал некоторые имена столбцов в этом запросе, но это не должно повлиять на отладку этой проблемы.Я бью себя за это.Ничто из того, что я исследую в Интернете, не упоминало о том, что длина столбца является проблемой в результирующем запросе.
Вот вывод EXPLAIN ANALYZE
для «плохого» запроса:
Subquery Scan on table_view (cost=173.16..173.29 rows=1 width=436) (actual time=648.470..800.577 rows=60 loops=1)
-> GroupAggregate (cost=173.16..173.28 rows=1 width=103) (actual time=648.468..800.552 rows=60 loops=1)
Group Key: dhci.id, wfciwf.id, dutm.account_id
Filter: (((array_append('{}'::integer[], dhci.cid) && '{28890,21166,28891,29581,29583,22378,22380,22733,28924,28925,28926,28927,28478,41014}'::integer[]) OR (array_agg(DISTIN
CT dhamti.member_id) && '{11125}'::integer[])) AND ((NOT dhci.hidden) OR (array_agg(DISTINCT dhamti.member_id) && '{11125}'::integer[])))
-> Sort (cost=173.16..173.17 rows=1 width=103) (actual time=647.727..685.155 rows=172000 loops=1)
Sort Key: dhci.id, wfciwf.id, dutm.account_id
Sort Method: external merge Disk: 16392kB
-> Nested Loop Left Join (cost=68.45..173.15 rows=1 width=103) (actual time=1.033..478.844 rows=172000 loops=1)
-> Nested Loop Left Join (cost=68.16..171.71 rows=1 width=99) (actual time=1.017..308.168 rows=172000 loops=1)
-> Nested Loop Left Join (cost=67.87..170.20 rows=1 width=95) (actual time=0.997..126.331 rows=172000 loops=1)
-> Nested Loop Left Join (cost=67.58..168.77 rows=1 width=91) (actual time=0.978..26.478 rows=33400 loops=1)
-> Nested Loop Left Join (cost=67.16..165.68 rows=1 width=87) (actual time=0.960..4.997 rows=3700 loops=1)
-> Nested Loop Left Join (cost=66.73..162.71 rows=1 width=83) (actual time=0.949..2.572 rows=410 loops=1)
-> Nested Loop Left Join (cost=66.44..161.59 rows=1 width=79) (actual time=0.939..2.121 rows=60 loops=1)
-> Nested Loop (cost=66.02..154.64 rows=1 width=75) (actual time=0.926..1.818 rows=60 loops=1)
-> Nested Loop (cost=65.59..148.07 rows=1 width=66) (actual time=0.902..1.446 rows=60 loops=1)
-> Index Scan using dutm_8a089c2a on dutm (cost=0.29..9.40 rows=2 width=8) (actual time=0.017..0.028 rows=9 loops=1)
Index Cond: (account_id = 3289)
-> Bitmap Heap Scan on dhci (cost=65.31..69.33 rows=1 width=66) (actual time=0.137..0.148 rows=7 loops=9)
Recheck Cond: ((owner_member_id = dutm.id) AND (deadline IS NOT NULL) AND (deadline >= '2019-02-03 00:00:00+00'::timestamp with time zone) AND (deadline < '2019-04-15 00:00:00+00'::timestamp with time zone))
Heap Blocks: exact=36
-> BitmapAnd (cost=65.31..65.31 rows=1 width=0) (actual time=0.135..0.135 rows=0 loops=9)
-> Bitmap Index Scan on dhci_9adb17cb (cost=0.00..5.79 rows=182 width=0) (actual time=0.036..0.036 rows=167 loops=9)
Index Cond: (owner_member_id = dutm.id)
-> Bitmap Index Scan on dhci_deadline_ba8bd3addbfe7dc_uniq (cost=0.00..58.66 rows=2419 width=0) (actual time=0.263..0.263 rows=1727 loops=3)
Index Cond: ((deadline IS NOT NULL) AND (deadline >= '2019-02-03 00:00:00+00'::timestamp with time zone) AND (deadline < '2019-04-15 00:00:00+00'::timestamp with time zone))
-> Index Scan using wfciwf_pkey on wfciwf (cost=0.42..6.55 rows=1 width=13) (actual time=0.005..0.005 rows=1 loops=60)
Index Cond: (id = dhci.workflow_state_id)
Filter: (((current_status)::text <> 'killed'::text) AND ((current_status)::text <> 'parked'::text))
-> Index Scan using dhamti_d7bbcb82 on dhamti (cost=0.42..6.93 rows=2 width=8) (actual time=0.003..0.004 rows=1 loops=60)
Index Cond: (content_item_id = dhci.id)
-> Index Scan using dhcibs_6123fe8a on dhcibs (cost=0.29..1.10 rows=2 width=8) (actual time=0.003..0.005 rows=7 loops=60)
Index Cond: (ciid = dhci.id)
-> Index Scan using dhcit_6123fe8a on dhcit (cost=0.42..2.95 rows=2 width=8) (actual time=0.002..0.004 rows=9 loops=410)
Index Cond: (ciid = dhci.id)
-> Index Scan using ghcita_6123fe8a on ghcita (cost=0.42..3.07 rows=2 width=8) (actual time=0.002..0.003 rows=9 loops=3700)
Index Cond: (ciid = dhci.id)
-> Index Scan using dhcipc_6123fe8a on dhcipc (cost=0.29..1.41 rows=2 width=8) (actual time=0.001..0.002 rows=5 loops=33400)
Index Cond: (ciid = dhci.id)
-> Index Scan using dhcipt_6123fe8a on dhcipt (cost=0.29..1.49 rows=2 width=8) (actual time=0.001..0.001 rows=0 loops=172000)
Index Cond: (ciid = dhci.id)
-> Index Scan using dhcik_6123fe8a on dhcik (cost=0.29..1.41 rows=3 width=8) (actual time=0.001..0.001 rows=0 loops=172000)
Index Cond: (ciid = dhci.id)
Planning time: 8.219 ms
Execution time: 804.161 ms
(45 rows)