рдЖрдзреБрдирд┐рдХ CPU рд╣рд░реВрдорд╛ рдзреЗрд░реИ рдХреЛрд░рд╣рд░реВ рдЫрдиреНред рд╡рд░реНрд╖реМрдВрджреЗрдЦрд┐, рдЕрдиреБрдкреНрд░рдпреЛрдЧрд╣рд░реВрд▓реЗ рд╕рдорд╛рдирд╛рдиреНрддрд░ рд░реВрдкрдорд╛ рдбрд╛рдЯрд╛рдмреЗрд╕рдорд╛ рдкреНрд░рд╢реНрдирд╣рд░реВ рдкрдард╛рдЙрдБрджреИ рдЖрдПрдХрд╛ рдЫрдиреНред рдпрджрд┐ рдпреЛ рддрд╛рд▓рд┐рдХрд╛рдорд╛ рдзреЗрд░реИ рдкрдЩреНрдХреНрддрд┐рд╣рд░реВрдорд╛ рд░рд┐рдкреЛрд░реНрдЯ рдХреНрд╡реЗрд░реА рд╣реЛ рднрдиреЗ, рдпреЛ рдзреЗрд░реИ CPUs рдкреНрд░рдпреЛрдЧ рдЧрд░реНрджрд╛ рдЫрд┐рдЯреЛ рдЪрд▓реНрдЫ, рд░ PostgreSQL рд╕рдВрд╕реНрдХрд░рдг 9.6 рджреЗрдЦрд┐ рдпреЛ рдЧрд░реНрди рд╕рдХреНрд╖рдо рднрдПрдХреЛ рдЫред
рдпреЛ рд╕рдорд╛рдирд╛рдиреНрддрд░ рдХреНрд╡реЗрд░реА рд╕реБрд╡рд┐рдзрд╛ рд▓рд╛рдЧреВ рдЧрд░реНрди 3 рд╡рд░реНрд╖ рд▓рд╛рдЧреНрдпреЛ - рд╣рд╛рдореАрд▓реЗ рдХреНрд╡реЗрд░реА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдирдХреЛ рд╡рд┐рднрд┐рдиреНрди рдЪрд░рдгрд╣рд░реВрдорд╛ рдХреЛрдб рдкреБрди: рд▓реЗрдЦреНрдиреБрдкрд░реНтАНрдпреЛред PostgreSQL 9.6 рд▓реЗ рдХреЛрдб рдердк рд╕реБрдзрд╛рд░ рдЧрд░реНрди рдкреВрд░реНрд╡рд╛рдзрд╛рд░ рдкреНрд░рд╕реНрддреБрдд рдЧрд░реНтАНрдпреЛред рдкрдЫрд┐рдХрд╛ рд╕рдВрд╕реНрдХрд░рдгрд╣рд░реВрдорд╛, рдЕрдиреНрдп рдкреНрд░рдХрд╛рд░рдХрд╛ рдкреНрд░рд╢реНрдирд╣рд░реВ рд╕рдорд╛рдирд╛рдиреНрддрд░ рд░реВрдкрдорд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЧрд░рд┐рдиреНрдЫред
рдкреНрд░рддрд┐рдмрдиреНрдзрд╣рд░реВ
- рдпрджрд┐ рд╕рдмреИ рдХреЛрд░ рдкрд╣рд┐рд▓реЗ рдиреИ рд╡реНрдпрд╕реНрдд рдЫрдиреН рднрдиреЗ рд╕рдорд╛рдирд╛рдиреНрддрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕рдХреНрд╖рдо рдирдЧрд░реНрдиреБрд╣реЛрд╕реН, рдЕрдиреНрдпрдерд╛ рдЕрдиреНрдп рдЕрдиреБрд░реЛрдзрд╣рд░реВ рд╕реБрд╕реНрдд рд╣реБрдиреЗрдЫрдиреНред
- рд╕рдмреИрднрдиреНрджрд╛ рдорд╣рддреНрддреНрд╡рдкреВрд░реНрдг рдХреБрд░рд╛, рдЙрдЪреНрдЪ WORK_MEM рдорд╛рдирд╣рд░реВрд╕рдБрдЧ рд╕рдорд╛рдирд╛рдиреНрддрд░ рдкреНрд░рд╢реЛрдзрдирд▓реЗ рдзреЗрд░реИ рдореЗрдореЛрд░реА рдкреНрд░рдпреЛрдЧ рдЧрд░реНрджрдЫ - рдкреНрд░рддреНрдпреЗрдХ рд╣реНрдпрд╛рд╕ рдЬреЛрдЗрди рд╡рд╛ рдХреНрд░рдордмрджреНрдзрд▓реЗ work_mem рдореЗрдореЛрд░реА рд▓рд┐рдиреНрдЫред
- рдХрдо рд╡рд┐рд▓рдореНрдмрддрд╛ OLTP рдкреНрд░рд╢реНрдирд╣рд░реВ рд╕рдорд╛рдирд╛рдиреНрддрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рджреНрд╡рд╛рд░рд╛ рджреНрд░реБрдд рдЧрд░реНрди рд╕рдХрд┐рдБрджреИрдиред рд░ рдпрджрд┐ рдХреНрд╡реЗрд░реАрд▓реЗ рдПрдЙрдЯрд╛ рдкрдЩреНрдХреНрддрд┐ рдлрд░реНрдХрд╛рдЙрдБрдЫ рднрдиреЗ, рд╕рдорд╛рдирд╛рдиреНрддрд░ рдкреНрд░рд╢реЛрдзрдирд▓реЗ рдорд╛рддреНрд░ рдпрд╕рд▓рд╛рдИ рдврд┐рд▓реЛ рдЧрд░реНрдиреЗрдЫред
- рд╡рд┐рдХрд╛рд╕рдХрд░реНрддрд╛рд╣рд░реВ TPC-H рдмреЗрдиреНрдЪрдорд╛рд░реНрдХ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рдорди рдкрд░рд╛рдЙрдБрдЫрдиреНред рд╣реБрдирд╕рдХреНрдЫ рддрдкрд╛рдИрдВрд╕рдБрдЧ рд╕рдорд╛рдирд╛рдиреНрддрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдирдХреЛ рд▓рд╛рдЧрд┐ рд╕рдорд╛рди рдкреНрд░рд╢реНрдирд╣рд░реВ рдЫрдиреНред
- рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд▓рдХ рдмрд┐рдирд╛ рдорд╛рддреНрд░ SELECT рдХреНрд╡реЗрд░реАрд╣рд░реВ рд╕рдорд╛рдирд╛рдиреНрддрд░ рд░реВрдкрдорд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЧрд░рд┐рдиреНрдЫред
- рдХрд╣рд┐рд▓реЗрдХрд╛рд╣реАрдБ рдЙрдЪрд┐рдд рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛ рд╕рдорд╛рдирд╛рдиреНрддрд░ рдореЛрдбрдорд╛ рдЕрдиреБрдХреНрд░рдорд┐рдХ рддрд╛рд▓рд┐рдХрд╛ рд╕реНрдХреНрдпрд╛рдирд┐рдЩ рднрдиреНрджрд╛ рд░рд╛рдореНрд░реЛ рд╣реБрдиреНрдЫред
- рдкрдЬрд┐рдЩ рдХреНрд╡реЗрд░реАрд╣рд░реВ рд░ рдХрд░реНрд╕рд░рд╣рд░реВ рд╕рдорд░реНрдерд┐рдд рдЫреИрдирдиреНред
- рд╕рдЮреНрдЭреНрдпрд╛рд▓ рдкреНрд░рдХрд╛рд░реНрдпрд╣рд░реВ рд░ рдХреНрд░рдордмрджреНрдз рд╕реЗрдЯ рд╕рдордЧреНрд░ рдкреНрд░рдХрд╛рд░реНрдпрд╣рд░реВ рд╕рдорд╛рдирд╛рдиреНрддрд░ рдЫреИрдирдиреНред
- рддрдкрд╛рдИрд▓реЗ I/O рдХрд╛рд░реНрдпрднрд╛рд░рдорд╛ рдХреЗрд╣рд┐ рдкрдирд┐ рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрдиреБрд╣реБрдиреНрдиред
- рддреНрдпрд╣рд╛рдБ рдХреБрдиреИ рд╕рдорд╛рдирд╛рдиреНрддрд░ рдХреНрд░рдордмрджреНрдз рдПрд▓реНрдЧреЛрд░рд┐рджрдорд╣рд░реВ рдЫреИрдирдиреНред рддрд░ рдкреНрд░рдХрд╛рд░рдХрд╛ рдкреНрд░рд╢реНрдирд╣рд░реВ рдХреЗрд╣реА рдкрдХреНрд╖рд╣рд░реВрдорд╛ рд╕рдорд╛рдирд╛рдиреНрддрд░ рд░реВрдкрдорд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫред
- рд╕рдорд╛рдирд╛рдиреНрддрд░ рдкреНрд░рд╢реЛрдзрди рд╕рдХреНрд╖рдо рдЧрд░реНрди CTE (WITH ...) рд▓рд╛рдИ рдиреЗрд╕реНрдЯреЗрдб SELECT рд╕рдБрдЧ рдмрджрд▓реНрдиреБрд╣реЛрд╕реНред
- рддреЗрд╕реНрд░реЛ-рдкрдХреНрд╖ рдбреЗрдЯрд╛ рд░реНрдпрд╛рдкрд░рд╣рд░реВрд▓реЗ рдЕрдЭреИ рд╕рдорд╛рдирд╛рдиреНрддрд░ рдкреНрд░рд╢реЛрдзрдирд▓рд╛рдИ рд╕рдорд░реНрдерди рдЧрд░реНрджреИрдирдиреН (рддрд░ рддрд┐рдиреАрд╣рд░реВрд▓реЗ рд╕рдХреНрдереЗ!)
- рдкреВрд░реНрдг рдмрд╛рд╣рд┐рд░реА рдЬреЛрдбрд┐ рд╕рдорд░реНрдерд┐рдд рдЫреИрдиред
- max_rows рд▓реЗ рд╕рдорд╛рдирд╛рдиреНрддрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЕрд╕рдХреНрд╖рдо рдкрд╛рд░реНрдЫред
- рдпрджрд┐ рдХреНрд╡реЗрд░реАрдорд╛ рд╕рдорд╛рдирд╛рдиреНрддрд░ рд╕реБрд░рдХреНрд╖рд┐рдд рдЪрд┐рдиреНрд╣рд┐рдд рдирднрдПрдХреЛ рдкреНрд░рдХрд╛рд░реНрдп рдЫ рднрдиреЗ, рдпреЛ рдПрдХрд▓ рдереНрд░реЗрдбреЗрдб рд╣реБрдиреЗрдЫред
- SERIALIZABLE рд▓реЗрдирджреЗрди рдЕрд▓рдЧрд╛рд╡ рд╕реНрддрд░ рд╕рдорд╛рдирд╛рдиреНрддрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЕрд╕рдХреНрд╖рдо рдЧрд░реНрджрдЫред
рдкрд░рд┐рдХреНрд╖рдг рд╡рд╛рддрд╛рд╡рд░рдг
PostgreSQL рд╡рд┐рдХрд╛рд╕рдХрд░реНрддрд╛рд╣рд░реВрд▓реЗ TPC-H рдмреЗрдиреНрдЪрдорд╛рд░реНрдХ рдкреНрд░рд╢реНрдирд╣рд░реВрдХреЛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕рдордп рдХрдо рдЧрд░реНрдиреЗ рдкреНрд░рдпрд╛рд╕ рдЧрд░реЗред рдмреЗрдиреНрдЪрдорд╛рд░реНрдХ рдбрд╛рдЙрдирд▓реЛрдб рдЧрд░реНрдиреБрд╣реЛрд╕реН рд░
- рдбрд╛рдЙрдирд▓реЛрдб TPC-H_Tools_v2.17.3.zip (рд╡рд╛ рдирдпрд╛рдБ рд╕рдВрд╕реНрдХрд░рдг)
TPC рдЕрдлрд╕рд╛рдЗрдЯрдмрд╛рдЯ . - makefile.suite рд▓рд╛рдИ Makefile рдорд╛ рдкреБрди: рдирд╛рдорд╛рдХрд░рдг рдЧрд░реНрдиреБрд╣реЛрд╕реН рд░ рдпрд╣рд╛рдБ рд╡рд░реНрдгрди рдЧрд░рд┐рдП рдЕрдиреБрд╕рд╛рд░ рдкрд░рд┐рд╡рд░реНрддрди рдЧрд░реНрдиреБрд╣реЛрд╕реН:
https://github.com/tvondra/pg_tpch ред рдореЗрдХ рдЖрджреЗрд╢рдХреЛ рд╕рд╛рде рдХреЛрдб рдХрдореНрдкрд╛рдЗрд▓ рдЧрд░реНрдиреБрд╣реЛрд╕реНред - рдбрд╛рдЯрд╛ рдЙрддреНрдкрдиреНрди рдЧрд░реНрдиреБрд╣реЛрд╕реН:
./dbgen -s 10
23 GB рдбрд╛рдЯрд╛рдмреЗрд╕ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрджрдЫред рд╕рдорд╛рдирд╛рдиреНрддрд░ рд░ рдЧреИрд░-рд╕рдорд╛рдирд╛рдиреНрддрд░ рдкреНрд░рд╢реНрдирд╣рд░реВрдХреЛ рдкреНрд░рджрд░реНрд╢рдирдорд╛ рднрд┐рдиреНрдирддрд╛ рд╣реЗрд░реНрди рдпреЛ рдкрд░реНрдпрд╛рдкреНрдд рдЫред - рдлрд╛рдЗрд▓рд╣рд░реВ рд░реВрдкрд╛рдиреНрддрд░рдг рдЧрд░реНрдиреБрд╣реЛрд╕реН
tbl
╨▓csv ╤Б for
╨╕sed
. - рднрдгреНрдбрд╛рд░ рдХреНрд▓реЛрди рдЧрд░реНрдиреБрд╣реЛрд╕реН
pg_tpch
рд░ рдлрд╛рдЗрд▓рд╣рд░реВ рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдЧрд░реНрдиреБрд╣реЛрд╕реНcsv
╨▓pg_tpch/dss/data
. - рдЖрджреЗрд╢рдХреЛ рд╕рд╛рде рдкреНрд░рд╢реНрдирд╣рд░реВ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрдиреБрд╣реЛрд╕реН
qgen
. - рдЖрджреЗрд╢рдХреЛ рд╕рд╛рде рдбрд╛рдЯрд╛рдмреЗрд╕рдорд╛ рдбрд╛рдЯрд╛ рд▓реЛрдб рдЧрд░реНрдиреБрд╣реЛрд╕реН
./tpch.sh
.
рд╕рдорд╛рдирд╛рдиреНрддрд░ рдХреНрд░рдорд┐рдХ рд╕реНрдХреНрдпрд╛рдирд┐рдЩ
рдпреЛ рд╕рдорд╛рдирд╛рдиреНрддрд░ рдкрдврд╛рдЗрдХреЛ рдХрд╛рд░рдг рд╣реЛрдЗрди, рддрд░ рдзреЗрд░реИ CPU рдХреЛрд░рд╣рд░реВрдорд╛ рдбрд╛рдЯрд╛ рдлреИрд▓рд┐рдПрдХреЛ рдХрд╛рд░рдгрд▓реЗ рдЫрд┐рдЯреЛ рд╣реБрди рд╕рдХреНрдЫред рдЖрдзреБрдирд┐рдХ рдЕрдкрд░реЗрдЯрд┐рдЩ рд╕рд┐рд╕реНрдЯрдорд╣рд░реВрдорд╛, PostgreSQL рдбрд╛рдЯрд╛ рдлрд╛рдЗрд▓рд╣рд░реВ рд░рд╛рдореНрд░реЛрд╕рдБрдЧ рдХреНрдпрд╛рд╕ рдЧрд░рд┐рдПрдХрд╛ рдЫрдиреНред рдЕрдЧрд╛рдбрд┐ рдкрдвреНрджрд╛, PG рдбреЗрдорди рдЕрдиреБрд░реЛрдзрд╣рд░реВ рднрдиреНрджрд╛ рднрдгреНрдбрд╛рд░рдгрдмрд╛рдЯ рдареВрд▓реЛ рдмреНрд▓рдХ рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрди рд╕рдореНрднрд╡ рдЫред рддреНрдпрд╕реИрд▓реЗ, рдХреНрд╡реЗрд░реА рдкреНрд░рджрд░реНрд╢рди рдбрд┐рд╕реНрдХ I/O рджреНрд╡рд╛рд░рд╛ рд╕реАрдорд┐рдд рдЫреИрдиред рдпрд╕рд▓реЗ рд╕реАрдкреАрдпреВ рдЪрдХреНрд░рд╣рд░реВ рдЙрдкрднреЛрдЧ рдЧрд░реНрджрдЫ:
- рддрд╛рд▓рд┐рдХрд╛ рдкреГрд╖реНрдард╣рд░реВрдмрд╛рдЯ рдПрдХ рдкрдЯрдХрдорд╛ рдкрдЩреНрдХреНрддрд┐рд╣рд░реВ рдкрдвреНрдиреБрд╣реЛрд╕реН;
- рд╕реНрдЯреНрд░рд┐рдЩ рдорд╛рди рд░ рд╕рд░реНрддрд╣рд░реВ рддреБрд▓рдирд╛ рдЧрд░реНрдиреБрд╣реЛрд╕реН
WHERE
.
рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдкреНрд░рд╢реНрди рдЪрд▓рд╛рдЙрдиреБрд╣реЛрд╕реН select
:
tpch=# explain analyze select l_quantity as sum_qty from lineitem where l_shipdate <= date '1998-12-01' - interval '105' day;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------
Seq Scan on lineitem (cost=0.00..1964772.00 rows=58856235 width=5) (actual time=0.014..16951.669 rows=58839715 loops=1)
Filter: (l_shipdate <= '1998-08-18 00:00:00'::timestamp without time zone)
Rows Removed by Filter: 1146337
Planning Time: 0.203 ms
Execution Time: 19035.100 ms
рдХреНрд░рдорд┐рдХ рд╕реНрдХреНрдпрд╛рдирд▓реЗ рдПрдЧреНрд░реАрдЧреЗрд╕рди рдмрд┐рдирд╛ рдзреЗрд░реИ рдкрдЩреНрдХреНрддрд┐рд╣рд░реВ рдЙрддреНрдкрд╛рджрди рдЧрд░реНрдЫ, рддреНрдпрд╕реИрд▓реЗ рдХреНрд╡реЗрд░реА рдПрдХрд▓ CPU рдХреЛрд░рджреНрд╡рд╛рд░рд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЧрд░рд┐рдиреНрдЫред
рдпрджрд┐ рддрдкрд╛рдЗрдБ рдердкреНрдиреБрд╣реБрдиреНрдЫ рднрдиреЗ SUM()
, рддрдкрд╛рдИрд▓реЗ рджреЗрдЦреНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ рдХрд┐ рджреБрдИ рдХрд╛рд░реНрдпрдкреНрд░рд╡рд╛рд╣рд╣рд░реВрд▓реЗ рдХреНрд╡реЗрд░реАрдХреЛ рдЧрддрд┐ рдмрдврд╛рдЙрди рдорджреНрджрдд рдЧрд░реНрдиреЗрдЫ:
explain analyze select sum(l_quantity) as sum_qty from lineitem where l_shipdate <= date '1998-12-01' - interval '105' day;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------
Finalize Aggregate (cost=1589702.14..1589702.15 rows=1 width=32) (actual time=8553.365..8553.365 rows=1 loops=1)
-> Gather (cost=1589701.91..1589702.12 rows=2 width=32) (actual time=8553.241..8555.067 rows=3 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Partial Aggregate (cost=1588701.91..1588701.92 rows=1 width=32) (actual time=8547.546..8547.546 rows=1 loops=3)
-> Parallel Seq Scan on lineitem (cost=0.00..1527393.33 rows=24523431 width=5) (actual time=0.038..5998.417 rows=19613238 loops=3)
Filter: (l_shipdate <= '1998-08-18 00:00:00'::timestamp without time zone)
Rows Removed by Filter: 382112
Planning Time: 0.241 ms
Execution Time: 8555.131 ms
рд╕рдорд╛рдирд╛рдиреНрддрд░ рдПрдХрддреНрд░реАрдХрд░рдг
рд╕рдорд╛рдирд╛рдиреНрддрд░ рд╕реЗрдХ рд╕реНрдХреНрдпрд╛рди рдиреЛрдбрд▓реЗ рдЖрдВрд╢рд┐рдХ рдПрдХрддреНрд░реАрдХрд░рдгрдХреЛ рд▓рд╛рдЧрд┐ рдкрдЩреНрдХреНрддрд┐рд╣рд░реВ рдЙрддреНрдкрд╛рджрди рдЧрд░реНрджрдЫред "рдЖрдВрд╢рд┐рдХ рдХреБрд▓" рдиреЛрдбрд▓реЗ рдпреА рд░реЗрдЦрд╛рд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдЯреНрд░рд┐рдо рдЧрд░реНрджрдЫ SUM()
ред рдЕрдиреНрддрдорд╛, рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдмрд╛рдЯ SUM рдХрд╛рдЙрдиреНрдЯрд░ "рдЧрд╛рджрд░" рдиреЛрдбрджреНрд╡рд╛рд░рд╛ рд╕рдЩреНрдХрд▓рди рдЧрд░рд┐рдиреНрдЫред
рдЕрдиреНрддрд┐рдо рдкрд░рд┐рдгрд╛рдо "рдлрд╛рдЗрдирд▓рд╛рдЗрдЬ рдПрдЧреНрд░реАрдЧреЗрдЯ" рдиреЛрдб рджреНрд╡рд╛рд░рд╛ рдЧрдгрдирд╛ рдЧрд░рд┐рдиреНрдЫред рдпрджрд┐ рддрдкрд╛рдЗрдБрд╕рдБрдЧ рддрдкрд╛рдЗрдБрдХреЛ рдЖрдлреНрдиреИ рдПрдХрддреНрд░реАрдХрд░рдг рдХрд╛рд░реНрдпрд╣рд░реВ рдЫрдиреН рднрдиреЗ, рддрд┐рдиреАрд╣рд░реВрд▓рд╛рдИ "рд╕рдорд╛рдирд╛рдиреНрддрд░ рд╕реБрд░рдХреНрд╖рд┐рдд" рдХреЛ рд░реВрдкрдорд╛ рдЪрд┐рдиреНрд╣ рд▓рдЧрд╛рдЙрди рдирдмрд┐рд░реНрд╕рдиреБрд╣реЛрд╕реНред
рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛рд╣рд░реВрдХреЛ рд╕рдВрдЦреНрдпрд╛
рд╕рд░реНрднрд░ рдкреБрди: рд╕реБрд░реБ рдирдЧрд░реА рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛рд╣рд░реВрдХреЛ рд╕рдВрдЦреНрдпрд╛ рдмрдврд╛рдЙрди рд╕рдХрд┐рдиреНрдЫ:
explain analyze select sum(l_quantity) as sum_qty from lineitem where l_shipdate <= date '1998-12-01' - interval '105' day;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------
Finalize Aggregate (cost=1589702.14..1589702.15 rows=1 width=32) (actual time=8553.365..8553.365 rows=1 loops=1)
-> Gather (cost=1589701.91..1589702.12 rows=2 width=32) (actual time=8553.241..8555.067 rows=3 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Partial Aggregate (cost=1588701.91..1588701.92 rows=1 width=32) (actual time=8547.546..8547.546 rows=1 loops=3)
-> Parallel Seq Scan on lineitem (cost=0.00..1527393.33 rows=24523431 width=5) (actual time=0.038..5998.417 rows=19613238 loops=3)
Filter: (l_shipdate <= '1998-08-18 00:00:00'::timestamp without time zone)
Rows Removed by Filter: 382112
Planning Time: 0.241 ms
Execution Time: 8555.131 ms
рдпрд╣рд╛рдБ рдХреЗ рднрдЗрд░рд╣реЗрдХреЛ рдЫ? рддреНрдпрд╣рд╛рдБ реи рдЧреБрдгрд╛ рдмрдвреА рдХрд╛рд░реНрдп рдкреНрд░рдХреНрд░рд┐рдпрд╛рд╣рд░реВ рдерд┐рдП, рд░ рдЕрдиреБрд░реЛрдз рдорд╛рддреНрд░ рез.ремрелрепреп рдЧреБрдгрд╛ рдЫрд┐рдЯреЛ рднрдпреЛред рдЧрдгрдирд╛рд╣рд░реВ рд░реЛрдЪрдХ рдЫрдиреНред рд╣рд╛рдореАрд╕рдБрдЧ реи рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд░ рез рдиреЗрддрд╛ рдерд┐рдПред рдкрд░рд┐рд╡рд░реНрддрди рдкрдЫрд┐ рдпреЛ 2+1,6599 рднрдпреЛред
рд╕рдорд╛рдирд╛рдиреНрддрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдмрд╛рдЯ рд╣рд╛рдореНрд░реЛ рдЕрдзрд┐рдХрддрдо рдЧрддрд┐: 5/3 = 1,66(6) рдкрдЯрдХред
рдпрд╕рд▓реЗ рдХрд╕рд░реА рдХрд╛рдо рдЧрд░реНрдЫ?
рдкреНрд░рдХреНрд░рд┐рдпрд╛рд╣рд░реВ
рдЕрдиреБрд░реЛрдз рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕рдзреИрдВ рдЕрдЧреНрд░рдгреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕рдВрдЧ рд╕реБрд░реБ рд╣реБрдиреНрдЫред рдиреЗрддрд╛рд▓реЗ рд╕рдмреИ рдХреБрд░рд╛ рдЧреИрд░-рд╕рдорд╛рдирд╛рдиреНрддрд░ рд░ рдХреЗрд╣реА рд╕рдорд╛рдирд╛рдиреНрддрд░ рдкреНрд░рд╢реЛрдзрди рдЧрд░реНрдЫред рд╕рдорд╛рди рдЕрдиреБрд░реЛрдзрд╣рд░реВ рдЧрд░реНрдиреЗ рдЕрдиреНрдп рдкреНрд░рдХреНрд░рд┐рдпрд╛рд╣рд░реВрд▓рд╛рдИ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛рд╣рд░реВ рднрдирд┐рдиреНрдЫред рд╕рдорд╛рдирд╛рдиреНрддрд░ рдкреНрд░рд╢реЛрдзрди рдкреВрд░реНрд╡рд╛рдзрд╛рд░ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрджрдЫ
рдЕрдиреНрддрд░рдХреНрд░рд┐рдпрд╛
рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛рд╣рд░реВрд▓реЗ рд╕рдиреНрджреЗрд╢ рд▓рд╛рдо (рд╕рд╛рдЭреЗрджрд╛рд░реА рдореЗрдореЛрд░реАрдорд╛ рдЖрдзрд╛рд░рд┐рдд) рдорд╛рд░реНрдлрдд рдиреЗрддрд╛рд╕рдБрдЧ рд╕рдЮреНрдЪрд╛рд░ рдЧрд░реНрджрдЫред рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдорд╛ 2 рд▓рд╛рдорд╣рд░реВ рдЫрдиреН: рддреНрд░реБрдЯрд┐рд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ рд░ рдЯрдкрд▓рд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ред
рдХрддрд┐ рдХрд╛рд░реНрдпрдкреНрд░рд╡рд╛рд╣ рдЖрд╡рд╢реНрдпрдХ рдЫ?
рдиреНрдпреВрдирддрдо рд╕реАрдорд╛ рдкреНрдпрд╛рд░рд╛рдорд┐рдЯрд░ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЧрд░рд┐рдПрдХреЛ рдЫ max_parallel_workers_per_gather
max_parallel_workers size
max_worker_processes
рдпрджрд┐ рдпреЛ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЖрд╡рдВрдЯрд┐рдд рдЧрд░реНрди рд╕рдореНрднрд╡ рдерд┐рдПрди рднрдиреЗ, рдкреНрд░рд╢реЛрдзрди рдПрдХрд▓-рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╣реБрдиреЗрдЫред
рдХреНрд╡реЗрд░реА рдкреНрд▓рд╛рдирд░рд▓реЗ рддрд╛рд▓рд┐рдХрд╛ рд╡рд╛ рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛рдХреЛ рд╕рд╛рдЗрдЬрдХреЛ рдЖрдзрд╛рд░рдорд╛ рдХрд╛рд░реНрдпрдкреНрд░рд╡рд╛рд╣ рдШрдЯрд╛рдЙрди рд╕рдХреНрдЫред рдпрд╕рдХрд╛ рд▓рд╛рдЧрд┐ рдорд╛рдкрджрдгреНрдбрд╣рд░реВ рдЫрдиреН min_parallel_table_scan_size
min_parallel_index_scan_size
set min_parallel_table_scan_size='8MB'
8MB table => 1 worker
24MB table => 2 workers
72MB table => 3 workers
x => log(x / min_parallel_table_scan_size) / log(3) + 1 worker
рдкреНрд░рддреНрдпреЗрдХ рдкрдЯрдХ рддрд╛рд▓рд┐рдХрд╛ рднрдиреНрджрд╛ 3 рдЧреБрдгрд╛ рдареВрд▓реЛ рдЫ min_parallel_(index|table)_scan_size
, Postgres рд▓реЗ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдердкреНрдЫред рдХрд╛рд░реНрдпрдкреНрд░рд╡рд╛рд╣рдХреЛ рд╕рдВрдЦреНрдпрд╛ рд▓рд╛рдЧрддрдорд╛ рдЖрдзрд╛рд░рд┐рдд рдЫреИрдиред рд╕рд░реНрдХреБрд▓рд░ рдирд┐рд░реНрднрд░рддрд╛рд▓реЗ рдЬрдЯрд┐рд▓ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдирд▓рд╛рдИ рдЧрд╛рд╣реНрд░реЛ рдмрдирд╛рдЙрдБрдЫред рдпрд╕рдХреЛ рд╕рдЯреНрдЯрд╛, рдпреЛрдЬрдирд╛рдХрд╛рд░рд▓реЗ рд╕рд░рд▓ рдирд┐рдпрдорд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрджрдЫред
рдЕрднреНрдпрд╛рд╕рдорд╛, рдпреА рдирд┐рдпрдорд╣рд░реВ рдЙрддреНрдкрд╛рджрдирдХреЛ рд▓рд╛рдЧрд┐ рд╕рдзреИрдВ рдЙрдкрдпреБрдХреНрдд рд╣реБрдБрджреИрдирдиреН, рддреНрдпрд╕реИрд▓реЗ рддрдкрд╛рдИрдВрд▓реЗ рдПрдХ рд╡рд┐рд╢реЗрд╖ рддрд╛рд▓рд┐рдХрд╛рдХреЛ рд▓рд╛рдЧрд┐ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛рд╣рд░реВрдХреЛ рд╕рдВрдЦреНрдпрд╛ рдкрд░рд┐рд╡рд░реНрддрди рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ: ALTER TABLE ... SET (parallel_workers = N
).
рдХрд┐рди рд╕рдорд╛рдирд╛рдиреНрддрд░ рдкреНрд░рд╢реЛрдзрди рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдПрдХреЛ рдЫреИрди?
рдкреНрд░рддрд┐рдмрдиреНрдзрд╣рд░реВрдХреЛ рд▓рд╛рдореЛ рд╕реВрдЪреАрдХреЛ рдЕрддрд┐рд░рд┐рдХреНрдд, рддреНрдпрд╣рд╛рдБ рд▓рд╛рдЧрдд рдЬрд╛рдБрдЪрд╣рд░реВ рдкрдирд┐ рдЫрдиреН:
parallel_setup_cost
parallel_tuple_cost
рдиреЗрд╕реНрдЯреЗрдб рд▓реВрдк рдЬреЛрдбрд┐рдиреНрдЫ
PostgreSQL 9.6+ ╨╝╨╛╨╢╨╡╤В ╨▓╤Л╨┐╨╛╨╗╨╜╤П╤В╤М ╨▓╨╗╨╛╨╢╨╡╨╜╨╜╤Л╨╡ ╤Ж╨╕╨║╨╗╤Л ╨┐╨░╤А╨░╨╗╨╗╨╡╨╗╤М╨╜╨╛ тАФ ╤Н╤В╨╛ ╨┐╤А╨╛╤Б╤В╨░╤П ╨╛╨┐╨╡╤А╨░╤Ж╨╕╤П.
explain (costs off) select c_custkey, count(o_orderkey)
from customer left outer join orders on
c_custkey = o_custkey and o_comment not like '%special%deposits%'
group by c_custkey;
QUERY PLAN
--------------------------------------------------------------------------------------
Finalize GroupAggregate
Group Key: customer.c_custkey
-> Gather Merge
Workers Planned: 4
-> Partial GroupAggregate
Group Key: customer.c_custkey
-> Nested Loop Left Join
-> Parallel Index Only Scan using customer_pkey on customer
-> Index Scan using idx_orders_custkey on orders
Index Cond: (customer.c_custkey = o_custkey)
Filter: ((o_comment)::text !~~ '%special%deposits%'::text)
рд╕рдЩреНрдХрд▓рди рдЕрдиреНрддрд┐рдо рдЪрд░рдгрдорд╛ рд╣реБрдиреНрдЫ, рддреНрдпрд╕реИрд▓реЗ Nested Loop Left Join рдПрдХ рд╕рдорд╛рдирд╛рдиреНрддрд░ рд╕рдЮреНрдЪрд╛рд▓рди рд╣реЛред рд╕рдорд╛рдирд╛рдиреНрддрд░ рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛ рдорд╛рддреНрд░ рд╕реНрдХреНрдпрд╛рди рд╕рдВрд╕реНрдХрд░рдг 10 рдорд╛ рдорд╛рддреНрд░ рдкреНрд░рд╕реНрддреБрдд рдЧрд░рд┐рдПрдХреЛ рдерд┐рдпреЛред рдпрд╕рд▓реЗ рд╕рдорд╛рдирд╛рдиреНрддрд░ рдХреНрд░рдорд┐рдХ рд╕реНрдХреНрдпрд╛рдирд┐рдЩ рдЬрд╕реНрддреИ рдХрд╛рдо рдЧрд░реНрджрдЫред рдЕрд╡рд╕реНрдерд╛ c_custkey = o_custkey
рдкреНрд░рддрд┐ рдЧреНрд░рд╛рд╣рдХ рд╕реНрдЯреНрд░рд┐рдЩ рдПрдХ рдЕрд░реНрдбрд░ рдкрдвреНрдЫред рддреНрдпрд╕реИрд▓реЗ рдпреЛ рд╕рдорд╛рдирд╛рдиреНрддрд░ рдЫреИрдиред
рд╣реНрдпрд╛рд╕ рд╕рд╛рдореЗрд▓ рд╣реБрдиреБрд╣реЛрд╕реН
рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛рд▓реЗ PostgreSQL 11 рд╕рдореНрдо рдЖрдлреНрдиреИ рд╣реНрдпрд╛рд╕ рддрд╛рд▓рд┐рдХрд╛ рдмрдирд╛рдЙрдБрдЫред рд░ рдпрджрд┐ рдпреА рдЪрд╛рд░ рднрдиреНрджрд╛ рдмрдвреА рдкреНрд░рдХреНрд░рд┐рдпрд╛рд╣рд░реВ рдЫрдиреН рднрдиреЗ, рдХрд╛рд░реНрдпрд╕рдореНрдкрд╛рджрдирдорд╛ рд╕реБрдзрд╛рд░ рд╣реБрдБрджреИрдиред рдирдпрд╛рдБ рд╕рдВрд╕реНрдХрд░рдгрдорд╛, рд╣реНрдпрд╛рд╕ рддрд╛рд▓рд┐рдХрд╛ рд╕рд╛рдЭрд╛ рдЧрд░рд┐рдПрдХреЛ рдЫред рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛рд▓реЗ рд╣реНрдпрд╛рд╕ рддрд╛рд▓рд┐рдХрд╛ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрди WORK_MEM рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд╕рдХреНрдЫред
select
l_shipmode,
sum(case
when o_orderpriority = '1-URGENT'
or o_orderpriority = '2-HIGH'
then 1
else 0
end) as high_line_count,
sum(case
when o_orderpriority <> '1-URGENT'
and o_orderpriority <> '2-HIGH'
then 1
else 0
end) as low_line_count
from
orders,
lineitem
where
o_orderkey = l_orderkey
and l_shipmode in ('MAIL', 'AIR')
and l_commitdate < l_receiptdate
and l_shipdate < l_commitdate
and l_receiptdate >= date '1996-01-01'
and l_receiptdate < date '1996-01-01' + interval '1' year
group by
l_shipmode
order by
l_shipmode
LIMIT 1;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=1964755.66..1964961.44 rows=1 width=27) (actual time=7579.592..7922.997 rows=1 loops=1)
-> Finalize GroupAggregate (cost=1964755.66..1966196.11 rows=7 width=27) (actual time=7579.590..7579.591 rows=1 loops=1)
Group Key: lineitem.l_shipmode
-> Gather Merge (cost=1964755.66..1966195.83 rows=28 width=27) (actual time=7559.593..7922.319 rows=6 loops=1)
Workers Planned: 4
Workers Launched: 4
-> Partial GroupAggregate (cost=1963755.61..1965192.44 rows=7 width=27) (actual time=7548.103..7564.592 rows=2 loops=5)
Group Key: lineitem.l_shipmode
-> Sort (cost=1963755.61..1963935.20 rows=71838 width=27) (actual time=7530.280..7539.688 rows=62519 loops=5)
Sort Key: lineitem.l_shipmode
Sort Method: external merge Disk: 2304kB
Worker 0: Sort Method: external merge Disk: 2064kB
Worker 1: Sort Method: external merge Disk: 2384kB
Worker 2: Sort Method: external merge Disk: 2264kB
Worker 3: Sort Method: external merge Disk: 2336kB
-> Parallel Hash Join (cost=382571.01..1957960.99 rows=71838 width=27) (actual time=7036.917..7499.692 rows=62519 loops=5)
Hash Cond: (lineitem.l_orderkey = orders.o_orderkey)
-> Parallel Seq Scan on lineitem (cost=0.00..1552386.40 rows=71838 width=19) (actual time=0.583..4901.063 rows=62519 loops=5)
Filter: ((l_shipmode = ANY ('{MAIL,AIR}'::bpchar[])) AND (l_commitdate < l_receiptdate) AND (l_shipdate < l_commitdate) AND (l_receiptdate >= '1996-01-01'::date) AND (l_receiptdate < '1997-01-01 00:00:00'::timestamp without time zone))
Rows Removed by Filter: 11934691
-> Parallel Hash (cost=313722.45..313722.45 rows=3750045 width=20) (actual time=2011.518..2011.518 rows=3000000 loops=5)
Buckets: 65536 Batches: 256 Memory Usage: 3840kB
-> Parallel Seq Scan on orders (cost=0.00..313722.45 rows=3750045 width=20) (actual time=0.029..995.948 rows=3000000 loops=5)
Planning Time: 0.977 ms
Execution Time: 7923.770 ms
TPC-H рдмрд╛рдЯ рдХреНрд╡реЗрд░реА 12 рд╕реНрдкрд╖реНрдЯ рд░реВрдкрдорд╛ рд╕рдорд╛рдирд╛рдиреНрддрд░ рд╣реНрдпрд╛рд╕ рдЬрдбрд╛рди рджреЗрдЦрд╛рдЙрдБрдЫред рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛рд▓реЗ рд╕рд╛рдЭрд╛ рд╣реНрдпрд╛рд╕ рддрд╛рд▓рд┐рдХрд╛ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрди рдпреЛрдЧрджрд╛рди рдЧрд░реНрджрдЫред
рд╕рдореНрдорд┐рд▓рд┐рдд рд╣реБрдиреБрд╣реЛрд╕реН
рдорд░реНрдЬ рдЬреЛрдЗрди рдкреНрд░рдХреГрддрд┐рдорд╛ рдЧреИрд░-рд╕рдорд╛рдирд╛рдиреНрддрд░ рд╣реЛред рдпрджрд┐ рдпреЛ рдкреНрд░рд╢реНрдирдХреЛ рдЕрдиреНрддрд┐рдо рдЪрд░рдг рд╣реЛ рднрдиреЗ рдЪрд┐рдиреНрддрд╛ рдирдЧрд░реНрдиреБрд╣реЛрд╕реН - рдпреЛ рдЕрдЭреИ рдкрдирд┐ рд╕рдорд╛рдирд╛рдиреНрддрд░рдорд╛ рдЪрд▓реНрди рд╕рдХреНрдЫред
-- Query 2 from TPC-H
explain (costs off) select s_acctbal, s_name, n_name, p_partkey, p_mfgr, s_address, s_phone, s_comment
from part, supplier, partsupp, nation, region
where
p_partkey = ps_partkey
and s_suppkey = ps_suppkey
and p_size = 36
and p_type like '%BRASS'
and s_nationkey = n_nationkey
and n_regionkey = r_regionkey
and r_name = 'AMERICA'
and ps_supplycost = (
select
min(ps_supplycost)
from partsupp, supplier, nation, region
where
p_partkey = ps_partkey
and s_suppkey = ps_suppkey
and s_nationkey = n_nationkey
and n_regionkey = r_regionkey
and r_name = 'AMERICA'
)
order by s_acctbal desc, n_name, s_name, p_partkey
LIMIT 100;
QUERY PLAN
----------------------------------------------------------------------------------------------------------
Limit
-> Sort
Sort Key: supplier.s_acctbal DESC, nation.n_name, supplier.s_name, part.p_partkey
-> Merge Join
Merge Cond: (part.p_partkey = partsupp.ps_partkey)
Join Filter: (partsupp.ps_supplycost = (SubPlan 1))
-> Gather Merge
Workers Planned: 4
-> Parallel Index Scan using <strong>part_pkey</strong> on part
Filter: (((p_type)::text ~~ '%BRASS'::text) AND (p_size = 36))
-> Materialize
-> Sort
Sort Key: partsupp.ps_partkey
-> Nested Loop
-> Nested Loop
Join Filter: (nation.n_regionkey = region.r_regionkey)
-> Seq Scan on region
Filter: (r_name = 'AMERICA'::bpchar)
-> Hash Join
Hash Cond: (supplier.s_nationkey = nation.n_nationkey)
-> Seq Scan on supplier
-> Hash
-> Seq Scan on nation
-> Index Scan using idx_partsupp_suppkey on partsupp
Index Cond: (ps_suppkey = supplier.s_suppkey)
SubPlan 1
-> Aggregate
-> Nested Loop
Join Filter: (nation_1.n_regionkey = region_1.r_regionkey)
-> Seq Scan on region region_1
Filter: (r_name = 'AMERICA'::bpchar)
-> Nested Loop
-> Nested Loop
-> Index Scan using idx_partsupp_partkey on partsupp partsupp_1
Index Cond: (part.p_partkey = ps_partkey)
-> Index Scan using supplier_pkey on supplier supplier_1
Index Cond: (s_suppkey = partsupp_1.ps_suppkey)
-> Index Scan using nation_pkey on nation nation_1
Index Cond: (n_nationkey = supplier_1.s_nationkey)
"рдорд░реНрдЬ рдЬреЛрдЗрди" рдиреЛрдб "рдЧрд╛рджрд░ рдорд░реНрдЬ" рдорд╛рдерд┐ рдЕрд╡рд╕реНрдерд┐рдд рдЫред рддреНрдпрд╕реИрд▓реЗ рдорд░реНрдЬрд▓реЗ рд╕рдорд╛рдирд╛рдиреНрддрд░ рдкреНрд░рд╢реЛрдзрди рдкреНрд░рдпреЛрдЧ рдЧрд░реНрджреИрдиред рддрд░ "рд╕рдорд╛рдирд╛рдиреНрддрд░ рд╕реВрдЪрдХрд╛рдВрдХ рд╕реНрдХреНрдпрд╛рди" рдиреЛрдб рдЕрдЭреИ рдкрдирд┐ рдЦрдгреНрдбрдХреЛ рд╕рд╛рде рдорджреНрджрдд рдЧрд░реНрджрдЫ part_pkey
.
рдЦрдгреНрдбрд╣рд░реВ рджреНрд╡рд╛рд░рд╛ рдЬрдбрд╛рди
PostgreSQL 11 рдорд╛
tpch=# set enable_partitionwise_join=t;
tpch=# explain (costs off) select * from prt1 t1, prt2 t2
where t1.a = t2.b and t1.b = 0 and t2.b between 0 and 10000;
QUERY PLAN
---------------------------------------------------
Append
-> Hash Join
Hash Cond: (t2.b = t1.a)
-> Seq Scan on prt2_p1 t2
Filter: ((b >= 0) AND (b <= 10000))
-> Hash
-> Seq Scan on prt1_p1 t1
Filter: (b = 0)
-> Hash Join
Hash Cond: (t2_1.b = t1_1.a)
-> Seq Scan on prt2_p2 t2_1
Filter: ((b >= 0) AND (b <= 10000))
-> Hash
-> Seq Scan on prt1_p2 t1_1
Filter: (b = 0)
tpch=# set parallel_setup_cost = 1;
tpch=# set parallel_tuple_cost = 0.01;
tpch=# explain (costs off) select * from prt1 t1, prt2 t2
where t1.a = t2.b and t1.b = 0 and t2.b between 0 and 10000;
QUERY PLAN
-----------------------------------------------------------
Gather
Workers Planned: 4
-> Parallel Append
-> Parallel Hash Join
Hash Cond: (t2_1.b = t1_1.a)
-> Parallel Seq Scan on prt2_p2 t2_1
Filter: ((b >= 0) AND (b <= 10000))
-> Parallel Hash
-> Parallel Seq Scan on prt1_p2 t1_1
Filter: (b = 0)
-> Parallel Hash Join
Hash Cond: (t2.b = t1.a)
-> Parallel Seq Scan on prt2_p1 t2
Filter: ((b >= 0) AND (b <= 10000))
-> Parallel Hash
-> Parallel Seq Scan on prt1_p1 t1
Filter: (b = 0)
рдореБрдЦреНрдп рдХреБрд░рд╛ рдпреЛ рд╣реЛ рдХрд┐ рдЦрдгреНрдбрд╣рд░реВрдорд╛ рдЬрдбрд╛рди рд╕рдорд╛рдирд╛рдиреНрддрд░ рдЫ рдпрджрд┐ рдпреА рдЦрдгреНрдбрд╣рд░реВ рдкрд░реНрдпрд╛рдкреНрдд рдЫрдиреНред
рд╕рдорд╛рдирд╛рдиреНрддрд░ рдЬреЛрдбреНрдиреБрд╣реЛрд╕реН
рдпрд╣рд╛рдБ 2 рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛рд╣рд░реВ рдЪрд▓рд┐рд░рд╣реЗрдХрд╛ рдЫрдиреН, рдпрджреНрдпрдкрд┐ 4 рд╕рдХреНрд╖рдо рдЫрдиреНред
tpch=# explain (costs off) select sum(l_quantity) as sum_qty from lineitem where l_shipdate <= date '1998-12-01' - interval '105' day union all select sum(l_quantity) as sum_qty from lineitem where l_shipdate <= date '2000-12-01' - interval '105' day;
QUERY PLAN
------------------------------------------------------------------------------------------------
Gather
Workers Planned: 2
-> Parallel Append
-> Aggregate
-> Seq Scan on lineitem
Filter: (l_shipdate <= '2000-08-18 00:00:00'::timestamp without time zone)
-> Aggregate
-> Seq Scan on lineitem lineitem_1
Filter: (l_shipdate <= '1998-08-18 00:00:00'::timestamp without time zone)
рд╕рдмреИрднрдиреНрджрд╛ рдорд╣рддреНрддреНрд╡рдкреВрд░реНрдг рдЪрд░
- WORK_MEM рд▓реЗ рдкреНрд░рддрд┐ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдореЛрд░реА рд╕реАрдорд┐рдд рдЧрд░реНрджрдЫ, рдкреНрд░рд╢реНрди рдорд╛рддреНрд░ рд╣реЛрдЗрди: work_mem рдкреНрд░рдХреНрд░рд┐рдпрд╛рд╣рд░реВ рдЬрдбрд╛рдирд╣рд░реВ = рдзреЗрд░реИ рдореЗрдореЛрд░реАред
- рдпреЛрдЬрдирд╛рдмрд╛рдЯ рд╕рдорд╛рдирд╛рдиреНрддрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдХреЛ рд▓рд╛рдЧрд┐ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЧрд░реНрдиреЗ рдХрд╛рд░реНрдпрдХреНрд░рдорд▓реЗ рдХрддрд┐ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛рд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреЗрдЫредmax_parallel_workers_per_gather
- рд╕рд░реНрднрд░рдорд╛ CPU рдХреЛрд░рд╣рд░реВрдХреЛ рд╕рдВрдЦреНрдпрд╛рдорд╛ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛рд╣рд░реВрдХреЛ рдХреБрд▓ рд╕рдВрдЦреНрдпрд╛ рд╕рдорд╛рдпреЛрдЬрди рдЧрд░реНрджрдЫредmax_worker_processes
- рд╕рдорд╛рди, рддрд░ рд╕рдорд╛рдирд╛рдиреНрддрд░ рдХрд╛рд░реНрдп рдкреНрд░рдХреНрд░рд┐рдпрд╛рд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐редmax_parallel_workers
рдкрд░рд┐рдгрд╛рдорд╣рд░реВ
рд╕рдВрд╕реНрдХрд░рдг 9.6 рдХреЛ рд░реВрдкрдорд╛, рд╕рдорд╛рдирд╛рдиреНрддрд░ рдкреНрд░рд╢реЛрдзрдирд▓реЗ рдзреЗрд░реИ рдкрдЩреНрдХреНрддрд┐рд╣рд░реВ рд╡рд╛ рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛рд╣рд░реВ рд╕реНрдХреНрдпрд╛рди рдЧрд░реНрдиреЗ рдЬрдЯрд┐рд▓ рдкреНрд░рд╢реНрдирд╣рд░реВрдХреЛ рдХрд╛рд░реНрдпрд╕рдореНрдкрд╛рджрдирдорд╛ рдзреЗрд░реИ рд╕реБрдзрд╛рд░ рдЧрд░реНрди рд╕рдХреНрдЫред PostgreSQL 10 рдорд╛, рд╕рдорд╛рдирд╛рдиреНрддрд░ рдкреНрд░рд╢реЛрдзрди рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд░реВрдкрдорд╛ рд╕рдХреНрд╖рдо рдЫред рдареВрд▓реЛ OLTP рдХрд╛рд░реНрдпрднрд╛рд░ рднрдПрдХреЛ рд╕рд░реНрднрд░рд╣рд░реВрдорд╛ рдпрд╕рд▓рд╛рдИ рдЕрд╕рдХреНрд╖рдо рдЧрд░реНрди рд╕рдореНрдЭрдиреБрд╣реЛрд╕реНред рдЕрдиреБрдХреНрд░рдорд┐рдХ рд╕реНрдХреНрдпрд╛рди рд╡рд╛ рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛ рд╕реНрдХреНрдпрд╛рдирд╣рд░реВрд▓реЗ рдзреЗрд░реИ рд╕реНрд░реЛрддрд╣рд░реВ рдЦрдкрдд рдЧрд░реНрджрдЫред рдпрджрд┐ рддрдкрд╛рдЗрдБ рд╕рдореНрдкреВрд░реНрдг рдбреЗрдЯрд╛рд╕реЗрдЯрдорд╛ рд░рд┐рдкреЛрд░реНрдЯ рдЪрд▓рд╛рдЙрдиреБрд╣реБрдиреНрди рднрдиреЗ, рддрдкрд╛рдЗрдБ рд╣рд░рд╛рдПрдХреЛ рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛рд╣рд░реВ рдердкреЗрд░ рд╡рд╛ рдЙрдЪрд┐рдд рд╡рд┐рднрд╛рдЬрди рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдХреНрд╡реЗрд░реА рдкреНрд░рджрд░реНрд╢рди рд╕реБрдзрд╛рд░ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫред
рд╕рдиреНрджрд░реНрдн
https://www.postgresql.org/docs/11/how-parallel-query-works.html https://www.postgresql.org/docs/11/parallel-plans.html http://ashutoshpg.blogspot.com/2017/12/partition-wise-joins-divide-and-conquer.html http://rhaas.blogspot.com/2016/04/postgresql-96-with-parallel-query-vs.html http://amitkapila16.blogspot.com/2015/11/parallel-sequential-scans-in-play.html https://write-skew.blogspot.com/2018/01/parallel-hash-for-postgresql.html http://rhaas.blogspot.com/2017/03/parallel-query-v2.html https://blog.2ndquadrant.com/parallel-monster-benchmark/ https://blog.2ndquadrant.com/parallel-aggregate/ https://www.depesz.com/2018/02/12/waiting-for-postgresql-11-support-parallel-btree-index-builds/ PostgreSQL 11 рдорд╛ рд╕рдорд╛рдирд╛рдиреНрддрд░рддрд╛
рд╕реНрд░реЛрдд: www.habr.com