172 похожих чатов

Всем привет. Почему запрос делает Seq scan по таблицам stage.branch_office

(57 тысяч строк), delivery_speed_src2region ( 22310 строк), delivery_speed_src2pvz (2875829 строк)? Несмотря на то, что в этих таблицах есть индексы по джойненым полям. seq_page_cost=1, поднимал до 30

https://pastebin.com/krCVYGmw

23 ответов

18 просмотров

EXPLAIN (analyze, buffers) нужен

max-chistyakov Автор вопроса

analyze означает, что запрос выполнился. Если он выполнится, меня он больше не будет интересовать — это однорзовый запрос. После того, как он выполнится, я про него забуду) Выполняется часов пять, поэтому могу только estimated

max chistyakov
analyze означает, что запрос выполнился. Если он ...

Тогда покажите SELECT version(); , EXPLAIN (VERBOSE, SETTINGS) и \d+ каждой таблицы, хотя бы.

Ответ: потому что это явно выгоднее с такими индексами — всё равно надо в таблицы идти за "вторым" полем, например (см. Output): -> Seq Scan on stage.branch_office bo (cost=0.00..1875.71 rows=57171 width=14) Output: bo.ctid, bo.office_id, bo.add_region_id А там есть только: "branch_office_pkey" PRIMARY KEY, btree (office_id)

max-chistyakov Автор вопроса
Yaroslav Schekin
Ответ: потому что это явно выгоднее с такими индек...

а Seq Scan ON report.delivery_speed_src2region sd2 - из-за того, что в output есть sd2.speed? Если да, не дешевле ли в таком случае просто было бы взять значение speed из строки, найденной по входящим в индекс полям region_id и src_office_id ?

max chistyakov
а Seq Scan ON report.delivery_speed_src2region sd2...

Да, из-за этого. По оценкам — нет, не дешевле (видимо, планировщик вычисляет, что всё равно понадобится большая часть значений из этой таблицы). Кстати, она всё равно крошечная, так что на практике о ней не стоит и думать.

max-chistyakov Автор вопроса
Yaroslav Schekin
Ответ: потому что это явно выгоднее с такими индек...

тот же запрос. Таблица delivery_speed_src2pvz (2875829 строк). Output: sd.speed, sd.ctid, sd.src_office_id, sd.dst_office_id. Всё, кроме ctid добавил в индекс. Почему по ней всё ещё идёт Seq Scan, хотя она явно не малая — почти 3 млн? https://pastebin.com/CCXCmFuQ

max chistyakov
тот же запрос. Таблица delivery_speed_src2pvz (287...

Тут уже оценки вот этой части: SELECT f.srid, f.create_dt, sd.speed FROM facts.srid_last_state AS f JOIN report.delivery_speed_src2pvz AS sd ON f.src_office_id = sd.src_office_id AND f.dst_office_id = sd.dst_office_id WHERE f.create_dt < '2022-11-01'::timestamptz AND f.first_date_stat IS NULL; отдельно нужно смотреть (и, возможно, и подробнее — с set enable_* = off;) — тут может быть несколько причин.

Мне вот куда удивительнее, что он планирует зачем-то index scan на facts.srid_last_state Там что, реально настолько большэ строк, чем тут выдаётся? (По моим прикидкам — миллионов 500 должно быть, чтобы оно переключилось.)

Ну и да... Не знаю, поможэт ли это хоть как-то, но work_mem=128M на этом жэлезе для одного важного запроса выглядит странно.

max chistyakov
facts.srid_last_state - 3,3 млрд строк

Тогда нельзя исключать, что он прав, да.

max-chistyakov Автор вопроса
Ilya Anfimov
Тогда нельзя исключать, что он прав, да.

то есть, с точки зрения оптимизатора, делать последовательное сканирование таблицы такого размера — оправдано?

max-chistyakov Автор вопроса
Ilya Anfimov
Какого — такого?

прошу прощения, неверно прочитал комментарий

Ну и да... Он думает, что тупо выборка srid по индэксу idx_srid_last_state__create_dt (create_dt < '2022-11-01 00:00:00+03'::TIMESTAMP WITH TIME zone) FILTER: (first_date_stat IS NULL) займёт треть этого времени. То есть пару часов. А обновление — втрое большэ, соответственно. Ну... Похожэ на правду, на самом деле. Но поставить 30 гиг work_mem я бы можэт и попробовал.

/offtopic весь CASE можно заменить на: f.create_dt + INTERVAL '1 HOUR' * COALESCE(sd.speed + 6, sd2.speed + 6, 84)

dennis
/offtopic весь CASE можно заменить на: f.create_d...

Это не оффтопик и совершэнно правильно — но топикстартеру вряд ли поможэт...

1. Если у вас есть время, то можно сделать индекс с фильтром WHERE (first_date_stat IS NULL) но судя по оценке (cost=0.58..106217414.34 ROWS=117158208 width=54) не поможет 2. UPDATE делать не сразу весь, а кусками (днями, месяцами), будет заметно быстрее

dennis
1. Если у вас есть время, то можно сделать индекс ...

>2. UPDATE делать не сразу весь, а кусками (днями, месяцами), будет заметно быстрее Если 5 часов подвисшэго вакуума не являются проблемой — то приведёт это только к тому, что оно будет делаться днями, хе-хе.

Как будет время, покажите пожалуйста два плана: 1. UPDATE facts.srid_last_state f SET first_date_stat = f.create_dt + INTERVAL '1 HOUR' * COALESCE(sd.speed + 6, sd2.speed + 6, 84) FROM stage.branch_office bo INNER JOIN report.delivery_speed_src2pvz sd ON TRUE AND sd.src_office_id = f.src_office_id AND sd.dst_office_id = f.dst_office_id INNER JOIN report.delivery_speed_src2region sd2 ON TRUE AND sd2.region_id = bo.add_region_id AND sd2.src_office_id = f.src_office_id WHERE TRUE AND f.create_dt BETWEEN '2022-10-01'::timestamptz AND '2022-11-01'::timestamptz AND f.first_date_stat IS NULL AND bo.office_id = f.dst_office_id; ----------------------------- 2. UPDATE facts.srid_last_state f SET first_date_stat = f.create_dt + INTERVAL '1 HOUR' * COALESCE(sd.speed + 6, sd2.speed + 6, 84) FROM stage.branch_office bo INNER JOIN report.delivery_speed_src2pvz sd ON TRUE AND sd.src_office_id = f.src_office_id AND sd.dst_office_id = f.dst_office_id INNER JOIN report.delivery_speed_src2region sd2 ON TRUE AND sd2.region_id = bo.add_region_id AND sd2.src_office_id = f.src_office_id WHERE TRUE AND f.create_dt < '2022-11-01'::timestamptz AND f.first_date_stat IS NULL AND bo.office_id = f.dst_office_id;

Похожие вопросы

Обсуждают сегодня

а через ESC-код ?
Alexey Kulakov
29
30500 за редактор? )
Владимир
47
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
13
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
в JclConsole объявлено так: function CtrlHandler(CtrlType: DWORD): BOOL; stdcall; - где ваше объявление с stdcall? у вас на картинке нет stdcall
Karagy
8
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
Ребят в СИ можно реализовать ООП?
Николай
33
program test; {$mode delphi} procedure proc(v: int32); overload; begin end; procedure proc(v: int64); overload; begin end; var x: uint64; begin proc(x); end. Уж не знаю...
notme
6
у вас два процесса. один посылает другому сигнал. у вас есть код обоих процессов? если всё не так - расскажите как оно на самом деле. а именно кто кому чего, есть-ли консоли,...
Karagy
6
Карта сайта