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 рд▓реЗ рд╕рдорд╛рдирд╛рдиреНрддрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЕрд╕рдХреНрд╖рдо рдкрд╛рд░реНрдЫред
  • рдпрджрд┐ рдХреНрд╡реЗрд░реАрдорд╛ рд╕рдорд╛рдирд╛рдиреНрддрд░ рд╕реБрд░рдХреНрд╖рд┐рдд рдЪрд┐рдиреНрд╣рд┐рдд рдирднрдПрдХреЛ рдкреНрд░рдХрд╛рд░реНрдп рдЫ рднрдиреЗ, рдпреЛ рдПрдХрд▓ рдереНрд░реЗрдбреЗрдб рд╣реБрдиреЗрдЫред
  • SERIALIZABLE рд▓реЗрдирджреЗрди рдЕрд▓рдЧрд╛рд╡ рд╕реНрддрд░ рд╕рдорд╛рдирд╛рдиреНрддрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЕрд╕рдХреНрд╖рдо рдЧрд░реНрджрдЫред

рдкрд░рд┐рдХреНрд╖рдг рд╡рд╛рддрд╛рд╡рд░рдг

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 рджреНрд╡рд╛рд░рд╛ рд╕реАрдорд┐рдд рдЫреИрдиред рдпрд╕рд▓реЗ рд╕реАрдкреАрдпреВ рдЪрдХреНрд░рд╣рд░реВ рдЙрдкрднреЛрдЧ рдЧрд░реНрджрдЫ:

  • рддрд╛рд▓рд┐рдХрд╛ рдкреГрд╖реНрдард╣рд░реВрдмрд╛рдЯ рдПрдХ рдкрдЯрдХрдорд╛ рдкрдЩреНрдХреНрддрд┐рд╣рд░реВ рдкрдвреНрдиреБрд╣реЛрд╕реН;
  • рд╕реНрдЯреНрд░рд┐рдЩ рдорд╛рди рд░ рд╕рд░реНрддрд╣рд░реВ рддреБрд▓рдирд╛ рдЧрд░реНрдиреБрд╣реЛрд╕реН 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) рдкрдЯрдХред

рдпрд╕рд▓реЗ рдХрд╕рд░реА рдХрд╛рдо рдЧрд░реНрдЫ?

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

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

рдЕрдиреНрддрд░рдХреНрд░рд┐рдпрд╛

рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛рд╣рд░реВрд▓реЗ рд╕рдиреНрджреЗрд╢ рд▓рд╛рдо (рд╕рд╛рдЭреЗрджрд╛рд░реА рдореЗрдореЛрд░реАрдорд╛ рдЖрдзрд╛рд░рд┐рдд) рдорд╛рд░реНрдлрдд рдиреЗрддрд╛рд╕рдБрдЧ рд╕рдЮреНрдЪрд╛рд░ рдЧрд░реНрджрдЫред рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдорд╛ 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 рдорд╛ рдЦрдгреНрдбрд╣рд░реВ рджреНрд╡рд╛рд░рд╛ рдЬрдбрд╛рди рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд░реВрдкрдорд╛ рдЕрд╕рдХреНрд╖рдо: рдпреЛ рдзреЗрд░реИ рдорд╣рдБрдЧреЛ рд╕рдордп рддрд╛рд▓рд┐рдХрд╛ рдЫред рд╕рдорд╛рди рд╡рд┐рднрд╛рдЬрди рднрдПрдХреЛ рддрд╛рд▓рд┐рдХрд╛рд╣рд░реВ рд╡рд┐рднрд╛рдЬрдирджреНрд╡рд╛рд░рд╛ рд╡рд┐рднрд╛рдЬрдирдорд╛ рдЬреЛрдбрд┐рди рд╕рдХрд┐рдиреНрдЫред рдпрд╕ рддрд░рд┐рдХрд╛рд▓реЗ Postgres рд▓реЗ рд╕рд╛рдиреЛ рд╣реНрдпрд╛рд╕ рддрд╛рд▓рд┐рдХрд╛рд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреЗрдЫред рдЦрдгреНрдбрд╣рд░реВрдХреЛ рдкреНрд░рддреНрдпреЗрдХ рдЬрдбрд╛рди рд╕рдорд╛рдирд╛рдиреНрддрд░ рд╣реБрди рд╕рдХреНрдЫред

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)

рдореБрдЦреНрдп рдХреБрд░рд╛ рдпреЛ рд╣реЛ рдХрд┐ рдЦрдгреНрдбрд╣рд░реВрдорд╛ рдЬрдбрд╛рди рд╕рдорд╛рдирд╛рдиреНрддрд░ рдЫ рдпрджрд┐ рдпреА рдЦрдгреНрдбрд╣рд░реВ рдкрд░реНрдпрд╛рдкреНрдд рдЫрдиреНред

рд╕рдорд╛рдирд╛рдиреНрддрд░ рдЬреЛрдбреНрдиреБрд╣реЛрд╕реН

рд╕рдорд╛рдирд╛рдиреНрддрд░ рдЬреЛрдбреНрдиреБрд╣реЛрд╕реН рд╡рд┐рднрд┐рдиреНрди рдХрд╛рд░реНрдпрдкреНрд░рд╡рд╛рд╣рд╣рд░реВрдорд╛ рд╡рд┐рднрд┐рдиреНрди рдмреНрд▓рдХрд╣рд░реВрдХреЛ рд╕рдЯреНрдЯрд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫред рдпреЛ рд╕рд╛рдорд╛рдиреНрдпрддрдпрд╛ UNION ALL рдкреНрд░рд╢реНрдирд╣рд░реВрдХреЛ рд╕рд╛рде рд╣реБрдиреНрдЫред рдмреЗрдлрд╛рдЗрджрд╛ рдХрдо рд╕рдорд╛рдирд╛рдиреНрддрд░рддрд╛ рд╣реЛ, рдХрд┐рдирдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛рд▓реЗ 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

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдердкреНрди