|
Cardinality estimation разное при обращение к view и непосредственно к таблицам
|
|||
---|---|---|---|
#18+
Всем привет. Дано представление : Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23.
Запрос вида select * from test_view where field1 = 1 and field2 = 2 должен инициировать выполнение только первого блока union all. Или нет ?)) Поля t1.field1 и t1.field2 обязательные int. Таблица table_1 секционирована по t1.field1 и есть индекс по t1.field2. Поиск в индексе осуществляется(index scan) - все хорошо, секция определена. Почему оценочное число строк для индекса по t1.field2 разное для следующих запросов ? Код: plsql 1.
и Код: plsql 1. 2. 3. 4. 5. 6.
В случае с view там просто космические цифры. Сильно завышено. Никто не сталкивался ? Postgresql 12.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
08.09.2020, 14:26 |
|
Cardinality estimation разное при обращение к view и непосредственно к таблицам
|
|||
---|---|---|---|
#18+
Да и почему появился bitmap index scan вместо обыкновенного index scan... ... |
|||
:
Нравится:
Не нравится:
|
|||
08.09.2020, 14:30 |
|
Cardinality estimation разное при обращение к view и непосредственно к таблицам
|
|||
---|---|---|---|
#18+
Афигеть блин... Из вьюхи убал union ы - оставил только первый запрос. И все сразу стало нормально. Что за фигня происходит ? Джойнить по условию null нельзя же. 2 И 3 запросы из вьюхи не должны же рассматриваться при условии выборки по двум полям. Их и в плане нету. К слову t2.field1 имеет алиас - забыл перенести. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.09.2020, 15:19 |
|
Cardinality estimation разное при обращение к view и непосредственно к таблицам
|
|||
---|---|---|---|
#18+
Товарищи, это какой-то прикол. На самом деле проблема очень серьезная. Тут ни вьюха ни union all не причем на самом деле. Я просто оставлю тут два запроса и их планы. Неверная оценка кол-ва строк сильно подрывает производительность других запросов, где эти подзапросы(вьюхи) используются. Каким то образом абсолютно ненужный left join все ломает.... ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2020, 11:07 |
|
Cardinality estimation разное при обращение к view и непосредственно к таблицам
|
|||
---|---|---|---|
#18+
Cristiano_Rivaldo, 1)прекратите присылать картинки вместо текста если хотите чтобы вам помощь оказали с такими вопросами (модератор) нужен полный текстовый запрос нужен полный текстовый explain analyze обязательно нужна версия базы (планировщик сильно по разному может работать в старых и новых базах) оценка количества строк надежная в общем случае не возможна... но всегда можно в запросе что то подхачить если очень надо или мешает. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2020, 11:24 |
|
Cardinality estimation разное при обращение к view и непосредственно к таблицам
|
|||
---|---|---|---|
#18+
Maxim Boguk, Нафига тут что-то подхачивать ? Тут же сразу видно - что это баг оптимизатора. Я к этому не сразу пришел. Думал что дело именно во вьюхах и их раскрывании. В MS SQL и Oracle все четко работает. Это простые запросы - ничего сложного в них нет. Если вам от этого легче, пожалуйста ловите : select * from ( select a.f_division,a.f_payments,a.n_amount from pe.fd_applications a INNER JOIN pe.fd_finances_ex fax ON fax.link = a.f_finances_ex UNION ALL select null::int as f_division,null::bigint as f_payments,null::numeric(18,2) as n_amount ) a where a.f_payments = 471596041 AND a.f_division = 1 ------------ select * from ( select a.f_division,a.f_payments,a.n_amount from pe.fd_applications a UNION ALL select null::int as f_division,null::bigint as f_payments,null::numeric(18,2) as n_amount ) a where a.f_payments = 471596041 AND a.f_division = 1 ----------- Hash Join (cost=4.74..71061.75 rows=31446 width=18) (actual time=0.174..0.201 rows=1 loops=1) Hash Cond: (a.f_finances_ex = fax.link) -> Append (cost=0.42..70971.49 rows=31446 width=22) (actual time=0.038..0.061 rows=1 loops=1) -> Index Scan using fd_applications_d1_o_f_payments_d_post_date_f_finances_ex_n_idx on fd_applications_d1_o a (cost=0.42..8297.79 rows=4432 width=22) (actual time=0.036..0.039 rows=1 loops=1) Index Cond: (f_payments = 471596041) Filter: (f_division = 1) -> Bitmap Heap Scan on fd_applications_d1_w a_1 (cost=857.79..62516.47 rows=27014 width=22) (actual time=0.018..0.019 rows=0 loops=1) Recheck Cond: (f_payments = 471596041) Filter: (f_division = 1) -> Bitmap Index Scan on fd_applications_d1_w_f_payments_d_post_date_f_finances_ex_n_idx (cost=0.00..851.04 rows=27014 width=0) (actual time=0.015..0.016 rows=0 loops=1) Index Cond: (f_payments = 471596041) -> Hash (cost=3.03..3.03 rows=103 width=4) (actual time=0.121..0.122 rows=103 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 12kB -> Seq Scan on fd_finances_ex fax (cost=0.00..3.03 rows=103 width=4) (actual time=0.012..0.061 rows=103 loops=1) Planning Time: 1.159 ms Execution Time: 0.304 ms --------- Append (cost=0.42..42.46 rows=12 width=18) (actual time=0.034..0.049 rows=1 loops=1) -> Index Scan using fd_applications_d1_o_f_payments_d_post_date_f_finances_ex_n_idx on fd_applications_d1_o a (cost=0.42..16.63 rows=5 width=18) (actual time=0.033..0.035 rows=1 loops=1) Index Cond: (f_payments = 471596041) Filter: (f_division = 1) -> Index Scan using fd_applications_d1_w_f_payments_d_post_date_f_finances_ex_n_idx on fd_applications_d1_w a_1 (cost=0.43..25.77 rows=7 width=18) (actual time=0.011..0.011 rows=0 loops=1) Index Cond: (f_payments = 471596041) Filter: (f_division = 1) Planning Time: 0.511 ms Execution Time: 0.093 ms Про версию я уже писал, но продублирую: PostgreSQL 12.4 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0, 64-bit ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2020, 11:38 |
|
Cardinality estimation разное при обращение к view и непосредственно к таблицам
|
|||
---|---|---|---|
#18+
Вот на всякий случай план без union all: select * from ( select a.f_division,a.f_payments,a.n_amount from pe.fd_applications a INNER JOIN pe.fd_finances_ex fax ON fax.link = a.f_finances_ex ) a where a.f_payments = 471596041 AND a.f_division = 1 ---- Hash Join (cost=42.61..46.28 rows=12 width=18) (actual time=0.068..0.112 rows=1 loops=1) Hash Cond: (fax.link = a.f_finances_ex) -> Seq Scan on fd_finances_ex fax (cost=0.00..3.03 rows=103 width=4) (actual time=0.010..0.028 rows=103 loops=1) -> Hash (cost=42.46..42.46 rows=12 width=22) (actual time=0.043..0.044 rows=1 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 9kB -> Append (cost=0.42..42.46 rows=12 width=22) (actual time=0.024..0.038 rows=1 loops=1) -> Index Scan using fd_applications_d1_o_f_payments_d_post_date_f_finances_ex_n_idx on fd_applications_d1_o a (cost=0.42..16.63 rows=5 width=22) (actual time=0.023..0.025 rows=1 loops=1) Index Cond: (f_payments = 471596041) Filter: (f_division = 1) -> Index Scan using fd_applications_d1_w_f_payments_d_post_date_f_finances_ex_n_idx on fd_applications_d1_w a_1 (cost=0.43..25.77 rows=7 width=22) (actual time=0.011..0.011 rows=0 loops=1) Index Cond: (f_payments = 471596041) Filter: (f_division = 1) Planning Time: 0.785 ms Execution Time: 0.171 ms INNER/LEFT сути не меняет. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2020, 12:45 |
|
Cardinality estimation разное при обращение к view и непосредственно к таблицам
|
|||
---|---|---|---|
#18+
Cristiano_Rivaldo, а покажите Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
и если не сложно - без потери форматирующих пробелов... какой то странный там план получается очень... и покажите структуру pe.fd_applications с индексами (не пойму откуда у вас append node взялась в запросе без union all) -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2020, 13:28 |
|
Cardinality estimation разное при обращение к view и непосредственно к таблицам
|
|||
---|---|---|---|
#18+
Maxim Boguk, Hash Join (cost=4.74..71061.75 rows=31446 width=18) (actual time=0.116..0.136 rows=1 loops=1) " Output: a.f_division, a.f_payments, a.n_amount" Inner Unique: true Hash Cond: (a.f_finances_ex = fax.link) -> Append (cost=0.42..70971.49 rows=31446 width=22) (actual time=0.028..0.046 rows=1 loops=1) -> Index Scan using fd_applications_d1_o_f_payments_d_post_date_f_finances_ex_n_idx on pe.fd_applications_d1_o a (cost=0.42..8297.79 rows=4432 width=22) (actual time=0.027..0.028 rows=1 loops=1) " Output: a.f_division, a.f_payments, a.n_amount, a.f_finances_ex" Index Cond: (a.f_payments = 471596041) Filter: (a.f_division = 1) -> Bitmap Heap Scan on pe.fd_applications_d1_w a_1 (cost=857.79..62516.47 rows=27014 width=22) (actual time=0.015..0.015 rows=0 loops=1) " Output: a_1.f_division, a_1.f_payments, a_1.n_amount, a_1.f_finances_ex" Recheck Cond: (a_1.f_payments = 471596041) Filter: (a_1.f_division = 1) -> Bitmap Index Scan on fd_applications_d1_w_f_payments_d_post_date_f_finances_ex_n_idx (cost=0.00..851.04 rows=27014 width=0) (actual time=0.012..0.013 rows=0 loops=1) Index Cond: (a_1.f_payments = 471596041) -> Hash (cost=3.03..3.03 rows=103 width=4) (actual time=0.074..0.075 rows=103 loops=1) Output: fax.link Buckets: 1024 Batches: 1 Memory Usage: 12kB -> Seq Scan on pe.fd_finances_ex fax (cost=0.00..3.03 rows=103 width=4) (actual time=0.009..0.040 rows=103 loops=1) Output: fax.link Planning Time: 1.015 ms Execution Time: 0.205 ms --------------------- create table if not exists pe.fd_applications ( link bigint generated by default as identity, f_division integer not null, f_subdivision smallint default 0 not null, f_debts smallint not null constraint fk_fd_applications_fs_debts references dbo.fs_debts deferrable, f_sale_categories smallint not null constraint fk_fd_applications_fs_sale_categories references dbo.fs_sale_categories deferrable, f_sub_operation_types smallint not null constraint fk_fd_applications_fs_sub_operation_types references dbo.fs_sub_operation_types deferrable, f_finances_ex integer not null constraint fk_fd_applications_fd_finances_ex references pe.fd_finances_ex deferrable, f_subscr integer not null constraint fk_fd_applications_sd_subscr references dbo.sd_subscr deferrable, f_applications bigint, f_charges bigint not null, f_payments bigint not null, f_payments_details bigint, f_payments_details_ref bigint, n_amount numeric(18,2) not null, n_tax_amount numeric(18,2) not null, n_dt_period_ct integer not null, n_dt_period_dt integer not null, n_period integer not null, n_period_pay integer not null, b_advance boolean default false not null, b_manual boolean default false not null, b_partial boolean default false not null, d_post_date date not null, d_reverse_date date, s_creator text default USER, s_owner text, s_modif_date timestamp with time zone, s_create_date timestamp with time zone default now(), link_imp text, s_archive smallint default 0 not null, s_audit_id_create bigint, s_audit_id_modif bigint ) partition by RANGE (f_division, s_archive); create index if not exists fd_applications_d0_o_n_period_idx on pe.fd_applications_d0_o (n_period); create index if not exists fd_applications_d0_o_f_payments_details_idx on pe.fd_applications_d0_o (f_payments_details); create index if not exists fd_applications_d0_o_f_payments_details_ref_idx on pe.fd_applications_d0_o (f_payments_details_ref); create index if not exists fd_applications_d0_o_f_subscr_f_finances_ex_n_amount_n_tax__idx on pe.fd_applications_d0_o (f_subscr, f_finances_ex, n_amount, n_tax_amount); create index if not exists fd_applications_d0_o_f_payments_d_post_date_f_finances_ex_n_idx on pe.fd_applications_d0_o (f_payments asc, d_post_date desc, f_finances_ex asc, n_amount asc, n_tax_amount asc); create index if not exists fd_applications_d0_o_f_charges_d_post_date_f_finances_ex_n__idx on pe.fd_applications_d0_o (f_charges asc, d_post_date desc, f_finances_ex asc, n_amount asc, n_tax_amount asc); create index if not exists fd_applications_d0_o_f_applications_idx on pe.fd_applications_d0_o (f_applications) where (f_applications IS NOT NULL); Для каждой секции не буду расписывать - там все одинаково в плане индексов ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2020, 13:39 |
|
Cardinality estimation разное при обращение к view и непосредственно к таблицам
|
|||
---|---|---|---|
#18+
Cristiano_Rivaldo, как у вас получается пробелы то терять? план должен выглядеть как Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24.
со всеми пробелами и форматированием иначе читать невозможно и главное невозможно интерпретировать... пробелы там важны чтобы понять "кто на ком стоял" ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2020, 14:07 |
|
Cardinality estimation разное при обращение к view и непосредственно к таблицам
|
|||
---|---|---|---|
#18+
Maxim Boguk, Возможно IDE их сжирает. Использую PyCharm. Просто копирую текст. В online интерпретаторах (например https://explain.dalibo.com/) все вроде отлично преобразовывается... ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2020, 14:13 |
|
Cardinality estimation разное при обращение к view и непосредственно к таблицам
|
|||
---|---|---|---|
#18+
Cristiano_Rivaldo, 1) analyze pe.fd_applications; analyze pe.fd_applications_d1_w; analyze pe.fd_applications_d1_o; 2) explain analyze select * from pe.fd_applications where f_payments = 471596041 and f_division = 1; 3) explain analyze select * from pe.fd_applications_d1_w where f_payments = 471596041 and f_division = 1; 4) explain analyze select * from pe.fd_applications_d1_o where f_payments = 471596041 and f_division = 1; что то таки странное происходит действительно. и самое интересное (напрямую в партицию обращаемся): explain analyze select * from ( select a.f_division,a.f_payments,a.n_amount from pe.fd_applications_d1_w a INNER JOIN pe.fd_finances_ex fax ON fax.link = a.f_finances_ex UNION ALL select null::int as f_division,null::bigint as f_payments,null::numeric(18,2) as n_amount ) a where a.f_payments = 471596041 AND a.f_division = 1 тут какая то грабля на стыке обработки union all c join и c партициями... надо докопать какая именно если вам конечно интересно и bug report написать скорее всего. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2020, 14:27 |
|
Cardinality estimation разное при обращение к view и непосредственно к таблицам
|
|||
---|---|---|---|
#18+
Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.
Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8.
... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2020, 14:28 |
|
Cardinality estimation разное при обращение к view и непосредственно к таблицам
|
|||
---|---|---|---|
#18+
Cristiano_Rivaldo, спасибо... чудеса творятся таки да... надо смотреть дальше -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2020, 14:34 |
|
Cardinality estimation разное при обращение к view и непосредственно к таблицам
|
|||
---|---|---|---|
#18+
Maxim Boguk, 2) explain analyze select * from pe.fd_applications where f_payments = 471596041 and f_division = 1; Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8.
3) explain analyze select * from pe.fd_applications_d1_w where f_payments = 471596041 and f_division = 1; Код: plaintext 1. 2. 3. 4.
4) explain analyze select * from pe.fd_applications_d1_o where f_payments = 471596041 and f_division = 1; Код: plaintext 1. 2. 3. 4.
5) explain analyze select * from ( select a.f_division,a.f_payments,a.n_amount from pe.fd_applications_d1_w a INNER JOIN pe.fd_finances_ex fax ON fax.link = a.f_finances_ex UNION ALL select null::int as f_division,null::bigint as f_payments,null::numeric(18,2) as n_amount ) a where a.f_payments = 471596041 AND a.f_division = 1 Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2020, 14:38 |
|
Cardinality estimation разное при обращение к view и непосредственно к таблицам
|
|||
---|---|---|---|
#18+
Cristiano_Rivaldo Maxim Boguk, 5) explain analyze select * from ( select a.f_division,a.f_payments,a.n_amount from pe.fd_applications_d1_w a INNER JOIN pe.fd_finances_ex fax ON fax.link = a.f_finances_ex UNION ALL select null::int as f_division,null::bigint as f_payments,null::numeric(18,2) as n_amount ) a where a.f_payments = 471596041 AND a.f_division = 1 Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Ага уже проще... теперь хотя бы мы знаем что партиционирование тут не причем. Это упрощает задачу поиска где проблема (причем сильно, потому что партиционирование оно новое весьма а вот остальные механизмы старые и не менялись сильно последние годы). Я пока беру паузу на подумать. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2020, 14:49 |
|
|
start [/forum/topic.php?fid=53&fpage=23&tid=1994478]: |
0ms |
get settings: |
10ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
32ms |
get topic data: |
13ms |
get forum data: |
3ms |
get page messages: |
53ms |
get tp. blocked users: |
2ms |
others: | 15ms |
total: | 149ms |
0 / 0 |