После обновления postgres я заметил, что один из запросов, которые я использовал, стал намного медленнее. После запуска EXPLAIN ANALYZE
я вижу, что теперь он использует другой индекс для того же запроса.
Среди других столбцов в моей таблице есть столбец applicationid
, который является внешним ключом BIGINT
, и у меня есть attributes
столбцы, которые являются jsonb
картой ключ / значение.
Описание в таблице coupons
(некоторые несущественные части были опущены):
+------------------------+--------------------------+-------------------------------------------------------+
| Column | Type | Modifiers |
|------------------------+--------------------------+-------------------------------------------------------|
| id | integer | not null default nextval('coupons_id_seq'::regclass) |
| created | timestamp with time zone | not null default now() |
| campaignid | bigint | |
| value | text | |
| expirydate | timestamp with time zone | |
| startdate | timestamp with time zone | |
| attributes | jsonb | not null default '{}'::jsonb |
| applicationid | bigint | |
| deleted | timestamp with time zone | |
| deleted_changelogid | bigint | not null default 0 |
| accountid | bigint | not null |
| recipientintegrationid | text | |
+------------------------+--------------------------+-------------------------------------------------------+
Indexes:
"coupons_applicationid_value_idx" UNIQUE, btree (applicationid, value) WHERE deleted IS NULL
"coupons_attrs_index" gin (attributes)
"coupons_recipientintegrationid_idx" btree (recipientintegrationid)
"coupons_value_trgm_idx" gin (value gin_trgm_ops)
Запрос I Я бегу (некоторые нерелевантные части были опущены):
EXPLAIN ANALYZE SELECT
*,
COUNT(*) OVER () AS total_rows
FROM
coupons
WHERE
deleted IS NULL
AND coupons.applicationid = 2
AND coupons.attributes @> '{"SessionId":"1070695459"}'
ORDER BY
id ASC
LIMIT 1000;
applicationid
не очень нам помогает. Ранее использовался индекс coupons_attrs_index
(более attributes
столбец), который дал очень хорошие результаты.
Однако после обновления планировщик запросов начал предпочитать индекс coupons_applicationid_value_idx
по некоторым причинам!
Вот вывод из EXPLAIN ANALYZE
(некоторые несущественные части были опущены):
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| QUERY PLAN |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| -> Sort (cost=64.09..64.10 rows=1 width=237) (actual time=3068.996..3068.996 rows=0 loops=1) |
| Sort Key: coupons.id |
| Sort Method: quicksort Memory: 25kB |
| -> WindowAgg (cost=0.86..64.08 rows=1 width=237) (actual time=3068.988..3068.988 rows=0 loops=1) |
| -> Nested Loop (cost=0.86..64.07 rows=1 width=229) (actual time=3068.985..3068.985 rows=0 loops=1) |
| -> Index Scan using coupons_applicationid_value_idx on coupons (cost=0.43..61.61 rows=1 width=213) (actual time=3068.984..3068.984 rows=0 loops=1) |
| Index Cond: (applicationid = 2) |
| Filter: (attributes @> '{"SessionId": "1070695459"}'::jsonb) |
| Rows Removed by Filter: 2344013 |
| Planning Time: 0.531 ms |
| Execution Time: 3069.076 ms |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
EXPLAIN
Time: 3.159s (3 seconds), executed in: 3.102s (3 seconds)
Может кто-нибудь помочь мне понять, почему планировщик запросов использует менее эффективный индекс (coupons_applicationid_value_idx
вместо * 1030) *) после обновления?
После добавления смешанного (BTREE + GIN) индекса в (applicationid, attributes)
этот индекс был выбран для эффективного решения проблемы. Я все еще хотел бы понять, что случилось, чтобы предсказать подобные проблемы в будущем.
[РЕДАКТИРОВАТЬ 31-01-20 11:02]: Проблема вернулась после 24 ч. Опять планировщик выбрал неверный индекс, и запрос стал медленным. Запуск простой analyze
решил это. Все еще очень странно, что это начало происходить только после обновления до PG 11.