Производительность с JSONB в PostgreSQL - PullRequest
1 голос
/ 06 апреля 2020

У меня возникли проблемы с запросами SQL в базе данных postgreSQL.

Мы работаем с таблицей с 300 000 строк.

Первый:

SELECT DISTINCT jsonb_object_keys("verbatim_verbatim"."meta") AS "meta_key" 
FROM "verbatim_verbatim" 
WHERE "verbatim_verbatim"."group_id" = 'dd1c8016-a0ea-49bb-914b-1c036fb3b0a1'::uuid

ОБЪЯСНЕНИЕ:

HashAggregate  (cost=25959.68..32449.08 rows=1278700 width=32) (actual time=274.130..274.144 rows=5 loops=1)
  Group Key: jsonb_object_keys(meta)
  Buffers: shared hit=18996 read=2308
  I/O Timings: read=44.623
  ->  Seq Scan on verbatim_verbatim  (cost=0.00..25766.87 rows=77123 width=32) (actual time=0.048..209.216 rows=390000 loops=1)
        Filter: (group_id = 'dd1c8016-a0ea-49bb-914b-1c036fb3b0a1'::uuid)
        Rows Removed by Filter: 263605
        Buffers: shared hit=18996 read=2308
        I/O Timings: read=44.623
Planning time: 103.268 ms
Execution time: 274.385 ms

Второе:

SELECT COUNT(*) AS "__count" 
FROM "verbatim_verbatim" 
WHERE ("verbatim_verbatim"."group_id" = 'dd1c8016-a0ea-49bb-914b-1c036fb3b0a1'::uuid 
       AND "verbatim_verbatim"."themes" IS NOT NULL)

ОБЪЯСНЕНИЕ:

Aggregate  (cost=25759.21..25759.22 rows=1 width=8) (actual 

time=165.949..165.949 rows=1 loops=1)
  Buffers: shared hit=19092 read=2212
  I/O Timings: read=52.237
  ->  Seq Scan on verbatim_verbatim  (cost=0.00..25574.06 rows=74059 width=0) (actual time=0.027..161.431 rows=78000 loops=1)
        Filter: ((themes IS NOT NULL) AND (group_id = 'dd1c8016-a0ea-49bb-914b-1c036fb3b0a1'::uuid))
        Rows Removed by Filter: 263605
        Buffers: shared hit=19092 read=2212
        I/O Timings: read=52.237
Planning time: 31.154 ms
Execution time: 166.015 ms

с анализом вакцины, как предлагается в комментарии:

Aggregate  (cost=25758.09..25758.10 rows=1 width=8) (actual time=120.529..120.529 rows=1 loops=1)
  Buffers: shared hit=20683 read=621
  I/O Timings: read=13.179
  ->  Seq Scan on verbatim_verbatim  (cost=0.00..25574.06 rows=73611 width=0) (actual time=0.027..116.082 rows=78000 loops=1)
        Filter: ((themes IS NOT NULL) AND (group_id = 'dd1c8016-a0ea-49bb-914b-1c036fb3b0a1'::uuid))
        Rows Removed by Filter: 263605
        Buffers: shared hit=20683 read=621
        I/O Timings: read=13.179
Planning time: 59.956 ms
Execution time: 120.595 ms

Вот моя база данных:

enter image description here

create table verbatim_verbatim
(
    id             serial                   not null
        constraint verbatim_verbatim_pkey
            primary key,
    verbatim_id    varchar(255)             not null,
    date_interview timestamp with time zone not null,
    text           varchar(160000)          not null,
    meta           jsonb                    not null,
    themes         jsonb,
    tonality       varchar(8),
    group_id       uuid                     not null
        constraint verbatim_verbatim_group_id_717c7b4d_fk_verbatim_
            references verbatim_verbatimgroup
            deferrable initially deferred,
    constraint verbatim_verbatim_verbatim_id_group_id_8d53a593_uniq
        unique (verbatim_id, group_id)
);

create index verbatim_verbatim_verbatim_id_7e805bd5
    on verbatim_verbatim (verbatim_id);

create index verbatim_verbatim_verbatim_id_7e805bd5_like
    on verbatim_verbatim (verbatim_id);

create index verbatim_verbatim_meta_89c00a2f
    on verbatim_verbatim (meta);

create index verbatim_verbatim_group_id_717c7b4d
    on verbatim_verbatim (group_id);

У вас есть идеи по поводу оптимизации этих запросов: /? Спасибо за помощь!

1 Ответ

0 голосов
/ 06 апреля 2020

Для того чтобы вычислить правильный результат, у него нет выбора, чтобы посетить все строки, где group_id = 'dd1c8016-a0ea-49bb-914b-1c036fb3b0a1', чтобы он мог проверить все ключи. Поскольку большая часть вашей таблицы удовлетворяет этому условию, это неизбежно займет некоторое время, и (для вашего первого запроса в любом случае) индексы вряд ли сильно помогут.

Это похоже на какую-то вспомогательную операцию. Почему вы запускаете это так часто, что вас волнует, если это займет четверть секунды?

...