PostgreSQL рдордзреНрдпреЗ рд╕рдорд╛рдВрддрд░ рдХреНрд╡реЗрд░реА

PostgreSQL рдордзреНрдпреЗ рд╕рдорд╛рдВрддрд░ рдХреНрд╡реЗрд░реА
рдЖрдзреБрдирд┐рдХ CPU рдордзреНрдпреЗ рднрд░рдкреВрд░ рдХреЛрд░ рдЖрд╣реЗрдд. рдЕрдиреЗрдХ рд╡рд░реНрд╖рд╛рдВрдкрд╛рд╕реВрди, рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╕рдорд╛рдВрддрд░рдкрдгреЗ рдбреЗрдЯрд╛рдмреЗрд╕реЗрд╕рд╡рд░ рдкреНрд░рд╢реНрди рдкрд╛рдард╡рдд рдЖрд╣реЗрдд. рдЬрд░ рддреА рдЯреЗрдмрд▓рдордзреАрд▓ рдПрдХрд╛рдзрд┐рдХ рдкрдВрдХреНрддреАрдВрд╡рд░реАрд▓ рдЕрд╣рд╡рд╛рд▓ рдХреНрд╡реЗрд░реА рдЕрд╕реЗрд▓, рддрд░ рдПрдХрд╛рдзрд┐рдХ CPUs рд╡рд╛рдкрд░рддрд╛рдирд╛ рддреЗ рдЬрд▓рдж рдЪрд╛рд▓рддреЗ рдЖрдгрд┐ PostgreSQL рдЖрд╡реГрддреНрддреА 9.6 рдкрд╛рд╕реВрди рд╣реЗ рдХрд░рдгреНрдпрд╛рд╕ рд╕рдХреНрд╖рдо рдЖрд╣реЗ.

рд╕рдорд╛рдВрддрд░ рдХреНрд╡реЗрд░реА рд╡реИрд╢рд┐рд╖реНрдЯреНрдп рд▓рд╛рдЧреВ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА 3 рд╡рд░реНрд╖реЗ рд▓рд╛рдЧрд▓реА - рдЖрдореНрд╣рд╛рд▓рд╛ рдХреНрд╡реЗрд░реА рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреАрдЪреНрдпрд╛ рд╡реЗрдЧрд╡реЗрдЧрд│реНрдпрд╛ рдЯрдкреНрдкреНрдпрд╛рдВрд╡рд░ рдХреЛрдб рдкреБрдиреНрд╣рд╛ рд▓рд┐рд╣рд╛рд╡рд╛ рд▓рд╛рдЧрд▓рд╛. PostgreSQL 9.6 рдиреЗ рдХреЛрдб рдЖрдгрдЦреА рд╕реБрдзрд╛рд░рдгреНрдпрд╛рд╕рд╛рдареА рдкрд╛рдпрд╛рднреВрдд рд╕реБрд╡рд┐рдзрд╛ рд╕рд╛рджрд░ рдХреЗрд▓реНрдпрд╛. рддреНрдпрд╛рдирдВрддрд░рдЪреНрдпрд╛ рдЖрд╡реГрддреНрддреНрдпрд╛рдВрдордзреНрдпреЗ, рдЗрддрд░ рдкреНрд░рдХрд╛рд░рдЪреНрдпрд╛ рдХреНрд╡реЗрд░реА рд╕рдорд╛рдВрддрд░рдкрдгреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХреЗрд▓реНрдпрд╛ рдЬрд╛рддрд╛рдд.

рдирд┐рд░реНрдмрдВрдз

  • рд╕рд░реНрд╡ рдХреЛрд░ рдЖрдзреАрдЪ рд╡реНрдпрд╕реНрдд рдЕрд╕рд▓реНрдпрд╛рд╕ рд╕рдорд╛рдВрддрд░ рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреА рд╕рдХреНрд╖рдо рдХрд░реВ рдирдХрд╛, рдЕрдиреНрдпрдерд╛ рдЗрддрд░ рд╡рд┐рдирдВрддреНрдпрд╛ рдХрдореА рд╣реЛрддреАрд▓.
  • рд╕рд░реНрд╡рд╛рдд рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ рдореНрд╣рдгрдЬреЗ, рдЙрдЪреНрдЪ WORK_MEM рдореВрд▓реНрдпрд╛рдВрд╕рд╣ рд╕рдорд╛рдВрддрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рднрд░рдкреВрд░ рдореЗрдорд░реА рд╡рд╛рдкрд░рддреЗ - рдкреНрд░рддреНрдпреЗрдХ рд╣реЕрд╢ рдЬреЙрдЗрди рдХрд┐рдВрд╡рд╛ рдХреНрд░рдорд╡рд╛рд░реА work_mem рдореЗрдорд░реА рдШреЗрддреЗ.
  • рдХрдореА рд╡рд┐рд▓рдВрдм OLTP рдХреНрд╡реЗрд░реА рд╕рдорд╛рдВрддрд░ рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреАрджреНрд╡рд╛рд░реЗ рд╡реЗрдЧрд╡рд╛рди рд╣реЛрдК рд╢рдХрдд рдирд╛рд╣реАрдд. рдЖрдгрд┐ рдЬрд░ рдХреНрд╡реЗрд░реА рдПрдХ рдкрдВрдХреНрддреА рдкрд░рдд рдХрд░рдд рдЕрд╕реЗрд▓, рддрд░ рд╕рдорд╛рдВрддрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗрд╡рд│ рддреЗ рдХрдореА рдХрд░реЗрд▓.
  • рд╡рд┐рдХрд╕рдХрд╛рдВрдирд╛ TPC-H рдмреЗрдВрдЪрдорд╛рд░реНрдХ рд╡рд╛рдкрд░рдгреЗ рдЖрд╡рдбрддреЗ. рдХрджрд╛рдЪрд┐рдд рддреБрдордЪреНрдпрд╛рдХрдбреЗ рдкрд░рд┐рдкреВрд░реНрдг рд╕рдорд╛рдВрддрд░ рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреАрд╕рд╛рдареА рд╕рдорд╛рди рдкреНрд░рд╢реНрди рдЕрд╕рддреАрд▓.
  • рдкреНрд░рд┐рдбрд┐рдХреЗрдЯ рд▓реЙрдХрд┐рдВрдЧрд╢рд┐рд╡рд╛рдп рдлрдХреНрдд SELECT рдХреНрд╡реЗрд░реА рд╕рдорд╛рдВрддрд░рдкрдгреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХреЗрд▓реНрдпрд╛ рдЬрд╛рддрд╛рдд.
  • рдХрдзреАрдХрдзреА рд╕рдорд╛рдВрддрд░ рдореЛрдбрдордзреНрдпреЗ рдЕрдиреБрдХреНрд░рдорд┐рдХ рдЯреЗрдмрд▓ рд╕реНрдХреЕрдирд┐рдВрдЧрдкреЗрдХреНрд╖рд╛ рдпреЛрдЧреНрдп рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛ рдЕрдзрд┐рдХ рдЪрд╛рдВрдЧрд▓реА рдЕрд╕рддреЗ.
  • рд╡рд┐рд░рд╛рдо рджреЗрдгреЗ рдХреНрд╡реЗрд░реА рдЖрдгрд┐ рдХрд░реНрд╕рд░ рд╕рдорд░реНрдерд┐рдд рдирд╛рд╣реАрдд.
  • рд╡рд┐рдВрдбреЛ рдлрдВрдХреНрд╢рдиреНрд╕ рдЖрдгрд┐ рдСрд░реНрдбрд░ рдХреЗрд▓реЗрд▓реЗ рд╕реЗрдЯ рдПрдЧреНрд░реАрдЧреЗрдЯ рдлрдВрдХреНрд╢рдиреНрд╕ рд╕рдорд╛рдВрддрд░ рдирд╛рд╣реАрдд.
  • I/O рд╡рд░реНрдХрд▓реЛрдбрдордзреНрдпреЗ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рд╣реАрд╣реА рдорд┐рд│рдд рдирд╛рд╣реА.
  • рдХреЛрдгрддреЗрд╣реА рд╕рдорд╛рдВрддрд░ рд╡рд░реНрдЧреАрдХрд░рдг рдЕрд▓реНрдЧреЛрд░рд┐рджрдо рдирд╛рд╣реАрдд. рдкрд░рдВрддреБ рдХрд╛рд╣реА рдмрд╛рдмреАрдВрдордзреНрдпреЗ рд╕рдорд╛рдВрддрд░рдкрдгреЗ рдХреНрд░рдорд╡рд╛рд░реАрд╕рд╣ рдХреНрд╡реЗрд░реА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХреЗрд▓реНрдпрд╛ рдЬрд╛рдК рд╢рдХрддрд╛рдд.
  • рд╕рдорд╛рдВрддрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕рдХреНрд╖рдо рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА CTE (WITH ...) рдиреЗрд╕реНрдЯреЗрдб SELECT рд╕рд╣ рдмрджрд▓рд╛.
  • рддреГрддреАрдп-рдкрдХреНрд╖ рдбреЗрдЯрд╛ рд░реЕрдкрд░ рдЕрджреНрдпрд╛рдк рд╕рдорд╛рдВрддрд░ рдкреНрд░рдХреНрд░рд┐рдпреЗрд╕ рд╕рдорд░реНрдерди рджреЗрдд рдирд╛рд╣реАрдд (рдкрд░рдВрддреБ рддреЗ рдХрд░реВ рд╢рдХрддрд╛рдд!)
  • рдкреВрд░реНрдг рдмрд╛рд╣реНрдп рд╕рд╛рдореАрд▓реАрдХрд░рдг рд╕рдорд░реНрдерд┐рдд рдирд╛рд╣реА.
  • max_rows рд╕рдорд╛рдВрддрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЕрдХреНрд╖рдо рдХрд░рддреЗ.
  • рдХреНрд╡реЗрд░реАрдордзреНрдпреЗ рд╕рдорд╛рдВрддрд░ рд╕реБрд░рдХреНрд╖рд┐рдд рдореНрд╣рдгреВрди рдЪрд┐рдиреНрд╣рд╛рдВрдХрд┐рдд рдирд╕рд▓реЗрд▓реЗ рдХрд╛рд░реНрдп рдЕрд╕рд▓реНрдпрд╛рд╕, рддреЗ рдПрдХрд▓ рдереНрд░реЗрдб рдХреЗрд▓реЗрд▓реЗ рдЕрд╕реЗрд▓.
  • рд╕реАрд░рд┐рдЕрд▓рд╛рдпрдЭреЗрдмрд▓ рд╡реНрдпрд╡рд╣рд╛рд░ рдЕрд▓рдЧрд╛рд╡ рдкрд╛рддрд│реА рд╕рдорд╛рдВрддрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЕрдХреНрд╖рдо рдХрд░рддреЗ.

рдЪрд╛рдЪрдгреА рд╡рд╛рддрд╛рд╡рд░рдг

PostgreSQL рд╡рд┐рдХрд╕рдХрд╛рдВрдиреА TPC-H рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдкреНрд░рд╢реНрдирд╛рдВрдЪрд╛ рдкреНрд░рддрд┐рд╕рд╛рдж рд╡реЗрд│ рдХрдореА рдХрд░рдгреНрдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХреЗрд▓рд╛. рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рд╛ рдЖрдгрд┐ рддреЗ PostgreSQL рдордзреНрдпреЗ рдЬреБрд│рд╡реВрди рдШреНрдпрд╛. рд╣рд╛ TPC-H рдмреЗрдВрдЪрдорд╛рд░реНрдХрдЪрд╛ рдЕрдирдзрд┐рдХреГрдд рд╡рд╛рдкрд░ рдЖрд╣реЗ - рдбреЗрдЯрд╛рдмреЗрд╕ рдХрд┐рдВрд╡рд╛ рд╣рд╛рд░реНрдбрд╡реЗрдЕрд░ рддреБрд▓рдирд╛рд╕рд╛рдареА рдирд╛рд╣реА.

  1. рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рд╛ TPC-H_Tools_v2.17.3.zip (рдХрд┐рдВрд╡рд╛ рдирд╡реАрди рдЖрд╡реГрддреНрддреА) TPC рдСрдлрд╕рд╛рдЗрдЯ рд╡рд░реВрди.
  2. makefile.suite рдЪреЗ рдирд╛рд╡ Makefile рд╡рд░ рдмрджрд▓рд╛ рдЖрдгрд┐ рдпреЗрдереЗ рд╡рд░реНрдгрди рдХреЗрд▓реНрдпрд╛рдкреНрд░рдорд╛рдгреЗ рдмрджрд▓рд╛: https://github.com/tvondra/pg_tpch . рдореЗрдХ рдХрдорд╛рдВрдбрд╕рд╣ рдХреЛрдб рд╕рдВрдХрд▓рд┐рдд рдХрд░рд╛.
  3. рдбреЗрдЯрд╛ рд╡реНрдпреБрддреНрдкрдиреНрди рдХрд░рд╛: ./dbgen -s 10 23 GB рдбреЗрдЯрд╛рдмреЗрд╕ рддрдпрд╛рд░ рдХрд░рддреЗ. рд╕рдорд╛рдВрддрд░ рдЖрдгрд┐ рдиреЙрди-рд╕рдорд╛рдВрддрд░ рдХреНрд╡реЗрд░реАрдЪреНрдпрд╛ рдХрд╛рд░реНрдпрдкреНрд░рджрд░реНрд╢рдирд╛рддреАрд▓ рдлрд░рдХ рдкрд╛рд╣рдгреНрдпрд╛рд╕рд╛рдареА рд╣реЗ рдкреБрд░реЗрд╕реЗ рдЖрд╣реЗ.
  4. рдлрд╛рдпрд▓реА рд░реВрдкрд╛рдВрддрд░рд┐рдд рдХрд░рд╛ tbl ╨▓ csv ╤Б for ╨╕ sed.
  5. рд░реЗрдкреЙрдЬрд┐рдЯрд░реА рдХреНрд▓реЛрди рдХрд░рд╛ pg_tpch рдЖрдгрд┐ рдлрд╛рдИрд▓реНрд╕ рдХреЙрдкреА рдХрд░рд╛ csv ╨▓ pg_tpch/dss/data.
  6. рдХрдорд╛рдВрдбрд╕рд╣ рдХреНрд╡реЗрд░реА рддрдпрд╛рд░ рдХрд░рд╛ qgen.
  7. рдХрдорд╛рдВрдбрд╕рд╣ рдбреЗрдЯрд╛рдмреЗрд╕рдордзреНрдпреЗ рдбреЗрдЯрд╛ рд▓реЛрдб рдХрд░рд╛ ./tpch.sh.

рд╕рдорд╛рдВрддрд░ рдЕрдиреБрдХреНрд░рдорд┐рдХ рд╕реНрдХреЕрдирд┐рдВрдЧ

рд╣реЗ рд╕рдорд╛рдВрддрд░ рд╡рд╛рдЪрдирд╛рдореБрд│реЗ рдЬрд▓рдж рд╣реЛрдК рд╢рдХрдд рдирд╛рд╣реА, рдкрд░рдВрддреБ рдбреЗрдЯрд╛ рдЕрдиреЗрдХ CPU рдХреЛрд░рдордзреНрдпреЗ рдкрд╕рд░рд▓реЗрд▓рд╛ рдЕрд╕рд▓реНрдпрд╛рдиреЗ. рдЖрдзреБрдирд┐рдХ рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯреАрдордордзреНрдпреЗ, PostgreSQL рдбреЗрдЯрд╛ рдлрд╛рдЗрд▓реНрд╕ рдЪрд╛рдВрдЧрд▓реНрдпрд╛ рдкреНрд░рдХрд╛рд░реЗ рдХреЕрд╢ рдХреЗрд▓реНрдпрд╛ рдЬрд╛рддрд╛рдд. рдкреБрдвреЗ рд╡рд╛рдЪреВрди, PG рдбрд┐рдорди рд╡рд┐рдирдВрддреНрдпрд╛рдВрдкреЗрдХреНрд╖рд╛ рд╕реНрдЯреЛрд░реЗрдЬрдордзреВрди рдореЛрдард╛ рдмреНрд▓реЙрдХ рдорд┐рд│рд╡рдгреЗ рд╢рдХреНрдп рдЖрд╣реЗ. рдореНрд╣рдгреВрди, рдбрд┐рд╕реНрдХ I/O рджреНрд╡рд╛рд░реЗ рдХреНрд╡реЗрд░реА рдХрд╛рд░реНрдпрдкреНрд░рджрд░реНрд╢рди рдорд░реНрдпрд╛рджрд┐рдд рдирд╛рд╣реА. рд╣реЗ рдпрд╛рд╕рд╛рдареА CPU рд╕рд╛рдпрдХрд▓ рд╡рд╛рдкрд░рддреЗ:

  • рдЯреЗрдмрд▓рдЪреНрдпрд╛ рдкреГрд╖реНрдард╛рдВрд╡рд░реВрди рдПрдХрд╛ рд╡реЗрд│реА рдПрдХ рдкрдВрдХреНрддреА рд╡рд╛рдЪрд╛;
  • рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореВрд▓реНрдпреЗ рдЖрдгрд┐ рд╢рд░реНрддреАрдВрдЪреА рддреБрд▓рдирд╛ рдХрд░рд╛ 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

рд╕рдорд╛рдВрддрд░ рдПрдХрддреНрд░реАрдХрд░рдг

рд╕рдорд╛рдВрддрд░ Seq рд╕реНрдХреЕрди рдиреЛрдб рдЖрдВрд╢рд┐рдХ рдПрдХрддреНрд░реАрдХрд░рдгрд╛рд╕рд╛рдареА рдкрдВрдХреНрддреА рддрдпрд╛рд░ рдХрд░рддреЛ. "рдЖрдВрд╢рд┐рдХ рдПрдХрддреНрд░рд┐рдд" рдиреЛрдб рд╡рд╛рдкрд░реВрди рдпрд╛ рдУрд│реА рдЯреНрд░рд┐рдо рдХрд░рддреЗ 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 рдкрдЯ рдЬрд▓рдж рдЭрд╛рд▓реА. рдЧрдгрд┐рддреЗ рдордиреЛрд░рдВрдЬрдХ рдЖрд╣реЗрдд. рдЖрдордЪреНрдпрд╛рдХрдбреЗ 2 рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЖрдгрд┐ 1 рдиреЗрддрд╛ рд╣реЛрддрд╛. рдмрджрд▓рд╛рдирдВрддрд░ рддреЗ 4+1 рдЭрд╛рд▓реЗ.

рд╕рдорд╛рдВрддрд░ рдкреНрд░рдХреНрд░рд┐рдпреЗрддреВрди рдЖрдордЪрд╛ рдХрдорд╛рд▓ рд╡реЗрдЧ: 5/3 = 1,66(6) рд╡реЗрд│рд╛.

рддреЗ рдХрд╕реЗ рдХрд╛рд░реНрдп рдХрд░рддреЗ?

рдкреНрд░рдХреНрд░рд┐рдпрд╛

рд╡рд┐рдирдВрддреАрдЪреА рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреА рдиреЗрд╣рдореА рдЕрдЧреНрд░рдЧрдгреНрдп рдкреНрд░рдХреНрд░рд┐рдпреЗрд╕рд╣ рд╕реБрд░реВ рд╣реЛрддреЗ. рдиреЗрддрд╛ рд╕рд░реНрд╡рдХрд╛рд╣реА рдЧреИрд░-рд╕рдорд╛рдВрддрд░ рдЖрдгрд┐ рдХрд╛рд╣реА рд╕рдорд╛рдВрддрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд░рддреЛ. рд╕рдорд╛рди рд╡рд┐рдирдВрддреНрдпрд╛ рдХрд░рдгрд╛рд▒реНрдпрд╛ рдЗрддрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдВрдирд╛ рдХрд╛рдордЧрд╛рд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореНрд╣рдгрддрд╛рдд. рд╕рдорд╛рдВрддрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдкрд╛рдпрд╛рднреВрдд рд╕реБрд╡рд┐рдзрд╛ рд╡рд╛рдкрд░рддреЗ рдбрд╛рдпрдиреЕрдорд┐рдХ рдкрд╛рд░реНрд╢реНрд╡рднреВрдореА рдХрд╛рдордЧрд╛рд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ (рдЖрд╡реГрддреНрддреА 9.4 рд╡рд░реВрди). PostgreSQL рдЪреЗ рдЗрддрд░ рднрд╛рдЧ рдереНрд░реЗрдбреНрд╕рдРрд╡рдЬреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╡рд╛рдкрд░рдд рдЕрд╕рд▓реНрдпрд╛рдиреЗ, 3 рд╡рд░реНрдХрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЕрд╕рд▓реЗрд▓реА рдХреНрд╡реЗрд░реА рдкрд╛рд░рдВрдкрд╛рд░рд┐рдХ рдкреНрд░рдХреНрд░рд┐рдпреЗрдкреЗрдХреНрд╖рд╛ 4 рдкрдЯ рдЬрд▓рдж рдЕрд╕реВ рд╢рдХрддреЗ.

рд╕рдВрд╡рд╛рдж

рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕рдВрджреЗрд╢ рд░рд╛рдВрдЧреЗрджреНрд╡рд╛рд░реЗ рдиреЗрддреНрдпрд╛рд╢реА рд╕рдВрд╡рд╛рдж рд╕рд╛рдзрддрд╛рдд (рд╕рд╛рдорд╛рдпрд┐рдХ рдореЗрдорд░реАрд╡рд░ рдЖрдзрд╛рд░рд┐рдд). рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХреНрд░рд┐рдпреЗрдордзреНрдпреЗ 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)

рд╕рдВрдХрд▓рди рд╢реЗрд╡рдЯрдЪреНрдпрд╛ рдЯрдкреНрдкреНрдпрд╛рд╡рд░ рд╣реЛрддреЗ, рдореНрд╣рдгреВрди рдиреЗрд╕реНрдЯреЗрдб рд▓реВрдк рд▓реЗрдлреНрдЯ рдЬреЙрдИрди рд╣реЗ рд╕рдорд╛рдВрддрд░ рдСрдкрд░реЗрд╢рди рдЖрд╣реЗ. рдкреЕрд░рд▓рд▓ рдЗрдВрдбреЗрдХреНрд╕ рдУрдиреНрд▓реА рд╕реНрдХреЕрди рдХреЗрд╡рд│ рдЖрд╡реГрддреНрддреА 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)

рдореБрдЦреНрдп рдЧреЛрд╖реНрдЯ рдЕрд╢реА рдЖрд╣реЗ рдХреА рд╣реЗ рд╡рд┐рднрд╛рдЧ рдкреБрд░реЗрд╕реЗ рдореЛрдареЗ рдЕрд╕рд▓реНрдпрд╛рд╕рдЪ рд╡рд┐рднрд╛рдЧрд╛рдВрдордзреАрд▓ рдХрдиреЗрдХреНрд╢рди рд╕рдорд╛рдВрддрд░ рдЖрд╣реЗ.

рд╕рдорд╛рдВрддрд░ рдЬреЛрдб

рд╕рдорд╛рдВрддрд░ рдЬреЛрдб рд╡реЗрдЧрд╡реЗрдЧрд│реНрдпрд╛ рд╡рд░реНрдХрдлреНрд▓реЛрдордзреНрдпреЗ рд╡реЗрдЧрд╡реЗрдЧрд│реНрдпрд╛ рдмреНрд▓реЙрдХреНрд╕рдРрд╡рдЬреА рд╡рд╛рдкрд░рд▓реЗ рдЬрд╛рдК рд╢рдХрддреЗ. рд╣реЗ рд╕рд╣рд╕рд╛ рдпреБрдирд┐рдпрди рд╕рд░реНрд╡ рдкреНрд░рд╢реНрдирд╛рдВрд╕рд╣ рд╣реЛрддреЗ. рдЧреИрд░рд╕реЛрдп рдХрдореА рд╕рдорд╛рдВрддрд░рддрд╛ рдЖрд╣реЗ, рдХрд╛рд░рдг рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗрд╡рд│ 1 рд╡рд┐рдирдВрддреАрд╡рд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд░рддреЗ.

рдпреЗрдереЗ 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 - рдпреЛрдЬрдиреЗрдЪреНрдпрд╛ рд╕рдорд╛рдВрддрд░ рдкреНрд░рдХреНрд░рд┐рдпреЗрд╕рд╛рдареА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рдгрд╛рд░рд╛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд┐рддреА рдХрд╛рдордЧрд╛рд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╡рд╛рдкрд░реЗрд▓.
  • max_worker_processes тАФ рд╕рд░реНрд╡реНрд╣рд░рд╡рд░реАрд▓ CPU рдХреЛрд░рдЪреНрдпрд╛ рд╕рдВрдЦреНрдпреЗрдд рдХрд╛рдордЧрд╛рд░ рдкреНрд░рдХреНрд░рд┐рдпреЗрдЪреА рдПрдХреВрдг рд╕рдВрдЦреНрдпрд╛ рд╕рдорд╛рдпреЛрдЬрд┐рдд рдХрд░рддреЗ.
  • max_parallel_workers - рд╕рдорд╛рди, рдкрд░рдВрддреБ рд╕рдорд╛рдВрддрд░ рдХрд╛рд░реНрдп рдкреНрд░рдХреНрд░рд┐рдпреЗрд╕рд╛рдареА.

рдкрд░рд┐рдгрд╛рдо

рдЖрд╡реГрддреНрддреА 9.6 рдиреБрд╕рд╛рд░, рд╕рдорд╛рдВрддрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЕрдиреЗрдХ рдкрдВрдХреНрддреА рдХрд┐рдВрд╡рд╛ рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛ рд╕реНрдХреЕрди рдХрд░рдгрд╛рд░реНтАНрдпрд╛ рдЬрдЯрд┐рд▓ рдкреНрд░рд╢реНрдирд╛рдВрдЪреНрдпрд╛ рдХрд╛рд░реНрдпрдкреНрд░рджрд░реНрд╢рдирд╛рдд рдореЛрдареНрдпрд╛ рдкреНрд░рдорд╛рдгрд╛рдд рд╕реБрдзрд╛рд░рдгрд╛ рдХрд░реВ рд╢рдХрддреЗ. PostgreSQL 10 рдордзреНрдпреЗ, рд╕рдорд╛рдВрддрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдбреАрдлреЙрд▓реНрдЯрдиреБрд╕рд╛рд░ рд╕рдХреНрд╖рдо рдХреЗрд▓реА рдЬрд╛рддреЗ. рдореЛрдареНрдпрд╛ OLTP рд╡рд░реНрдХрд▓реЛрдбрд╕рд╣ рд╕рд░реНрд╡реНрд╣рд░рд╡рд░ рддреЗ рдЕрдХреНрд╖рдо рдХрд░рдгреНрдпрд╛рдЪреЗ рд▓рдХреНрд╖рд╛рдд рдареЗрд╡рд╛. рдЕрдиреБрдХреНрд░рдорд┐рдХ рд╕реНрдХреЕрди рдХрд┐рдВрд╡рд╛ рдЗрдВрдбреЗрдХреНрд╕ рд╕реНрдХреЕрди рднрд░рдкреВрд░ рд╕рдВрд╕рд╛рдзрдиреЗ рд╡рд╛рдкрд░рддрд╛рдд. рддреБрдореНрд╣реА рд╕рдВрдкреВрд░реНрдг рдбреЗрдЯрд╛рд╕реЗрдЯрд╡рд░ рдЕрд╣рд╡рд╛рд▓ рдЪрд╛рд▓рд╡рдд рдирд╕рд▓реНрдпрд╛рд╕, рддреБрдореНрд╣реА рдлрдХреНрдд рдЧрд╣рд╛рд│ рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛ рдЬреЛрдбреВрди рдХрд┐рдВрд╡рд╛ рдпреЛрдЧреНрдп рд╡рд┐рднрд╛рдЬрди рд╡рд╛рдкрд░реВрди рдХреНрд╡реЗрд░реА рдХрд╛рд░реНрдпрдкреНрд░рджрд░реНрд╢рди рд╕реБрдзрд╛рд░реВ рд╢рдХрддрд╛.

рд╕рдВрджрд░реНрдн

рд╕реНрддреНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╛