Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.145.178.240] |
|
Данный раздел предназначается исключительно для обсуждения вопросов использования языка запросов SQL. Обсуждение общих вопросов, связанных с тематикой баз данных - обсуждаем в разделе "Базы данных: общие вопросы". Убедительная просьба - соблюдать "Правила форума" и не пренебрегать "Правильным оформлением своих тем". Прежде, чем создавать тему, имеет смысл заглянуть в раздел "Базы данных: FAQ", возможно там уже есть ответ. |
Сообщ.
#1
,
|
|
|
Всем дратути! )))
Есть таблица со множеством полей типа: CREATE TABLE big_data ( id serial NOT NULL, ... is_active boolean NOT NULL, source_id integer NOT NULL, CONSTRAINT big_data_pkey PRIMARY KEY (id) ); Есть общий индекс btree на is_active и source_id. Запрос во вновь созданной таблице на 7 млн. сгенерированных записей SELECT id FROM big_data WHERE is_active IS TRUE AND source_id=2 ORDER BY id DESC LIMIT 1; отрабатывает вполне себе шустро, а вот с боевого накатываю 7 млн.записей -- выполняется более получаса и не дает результатов. При этом в логе этот запрос показывается и EXPLAIN-ы (без выполнения) на обоих наборах данных почти одинаковые. В чем может быть причина? Или как можно диагностировать проблему? |
Сообщ.
#2
,
|
|
|
Какая СУБД? какая версия сервера? Отдельно на тесте и на продакшене.
Цитата piksel @ Есть общий индекс btree на is_active и source_id А показать в составе DDL - не? Цитата piksel @ WHERE is_active IS TRUE Это - серьёзно? вот прямо так и в запросе? Цитата piksel @ EXPLAIN-ы (без выполнения) на обоих наборах данных почти одинаковые. Почти одинаковые - это РАЗНЫЕ. В студию. |
Сообщ.
#3
,
|
|
|
Да, извиняюсь за неточности первоначального вопроса. Вроде немного проясняется. Всё дело в том, что есть 2 таблицы. Одна с рабочими данными, а другая тестовая для опытов.
Рабочая: CREATE TABLE public."big_data" ( "id" INTEGER NOT NULL DEFAULT NEXTVAL((pg_get_serial_sequence('"public"."big_data"'::text, 'id'::text))::regclass), ... source_id SMALLINT, is_active BOOLEAN DEFAULT TRUE, CONSTRAINT "pbig_data" PRIMARY KEY ("id") ) WITH ( OIDS=FALSE ); CREATE INDEX "ibig_data-source_id__is_active" ON public."big_data" USING btree (source_id, is_active) WHERE source_id IS NOT NULL AND is_active; и та на которой я всё тестирую, заполненная примерно таким же количеством данных: CREATE TABLE public.big_data ( id INTEGER NOT NULL DEFAULT NEXTVAL('big_data_id_seq'::regclass), text_data text, is_active BOOLEAN DEFAULT TRUE, source_id SMALLINT, CONSTRAINT big_data_pkey PRIMARY KEY (id) ) WITH ( OIDS=FALSE ); CREATE INDEX big_data_source_id_index ON public.big_data USING btree (source_id, is_active) WHERE source_id IS NOT NULL AND is_active; Так вот. Один и тот же запрос: EXPLAIN SELECT "id" FROM "big_data" WHERE source_id = 6 AND is_active ORDER BY "id" DESC LIMIT 1 и EXPLAIN SELECT id FROM big_data WHERE is_active AND source_id=2 ORDER BY id DESC LIMIT 1; даёт разные результаты - в одном индекс используется, в другом - нет: "Limit (cost=0.43..220.64 rows=1 width=4)" " -> Index Scan Backward using "pbig_data" on "big_data" (cost=0.43..10254585.72 rows=46567 width=4)" " Filter: (is_active AND (source_id = 6))" "Limit (cost=11.26..11.26 rows=1 width=4)" " -> Sort (cost=11.26..11.26 rows=3 width=4)" " Sort Key: id DESC" " -> Bitmap Heap Scan on big_data (cost=4.13..11.24 rows=3 width=4)" " Recheck Cond: ((source_id = 2) AND is_active)" " -> Bitmap Index Scan on big_data_source_id_index (cost=0.00..4.13 rows=3 width=0)" " Index Cond: (source_id = 2)" |
Сообщ.
#4
,
|
|
|
Цитата Akina @ Какая СУБД? какая версия сервера? ? |
Сообщ.
#5
,
|
|
|
Возникли три предположения:
1. Разница потому, что используются разные ид: 2 и 6. Попробовать одинаковые ид; 2. Статистики неправильные. Обновить статистики; 3. Запрос на рабочем сервере блокируется другими запросами. Попробуй грязное чтение; |
Сообщ.
#6
,
|
|
|
PostgreSQL 9.6
В общем, спасибо всем! Проблема решена. Не умею нормально строить индексы. Надо: CREATE INDEX big_data_source_id_index ON public.big_data USING btree (source_id, id) WHERE source_id IS NOT NULL AND is_active; |