PostgreSQL เชฎเชพเช‚ เชธเชฎเชพเช‚เชคเชฐ เชชเซเชฐเชถเซเชจเซ‹

PostgreSQL เชฎเชพเช‚ เชธเชฎเชพเช‚เชคเชฐ เชชเซเชฐเชถเซเชจเซ‹
เช†เชงเซเชจเชฟเช• CPU เชฎเชพเช‚ เช˜เชฃเชพ เชฌเชงเชพ เช•เซ‹เชฐเซ‹ เช›เซ‡. เชตเชฐเซเชทเซ‹เชฅเซ€, เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชกเซ‡เชŸเชพเชฌเซ‡เชเชจเซ‡ เชธเชฎเชพเช‚เชคเชฐ เชชเซเชฐเชถเซเชจเซ‹ เชฎเซ‹เช•เชฒเชคเซ€ เชฐเชนเซ€ เช›เซ‡. เชœเซ‹ เชคเซ‡ เช•เซ‹เชทเซเชŸเช•เชฎเชพเช‚ เชฌเชนเซเชตเชฟเชง เชชเช‚เช•เซเชคเชฟเช“ เชชเชฐ เชฐเชฟเชชเซ‹เชฐเซเชŸ เช•เซเชตเซ‡เชฐเซ€ เชนเซ‹เชฏ, เชคเซ‹ เชฌเชนเซเชตเชฟเชง CPU เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชคเซ€ เชตเช–เชคเซ‡ เชคเซ‡ เชตเชงเซ เชเชกเชชเชฅเซ€ เชšเชพเชฒเซ‡ เช›เซ‡, เช…เชจเซ‡ PostgreSQL เช†เชตเซƒเชคเซเชคเชฟ 9.6 เชฅเซ€ เช† เช•เชฐเชตเชพ เชธเช•เซเชทเชฎ เช›เซ‡.

เชธเชฎเชพเช‚เชคเชฐ เช•เซเชตเซ‡เชฐเซ€ เชธเซเชตเชฟเชงเชพเชจเซ‡ เช…เชฎเชฒเชฎเชพเช‚ เชฒเชพเชตเชตเชพเชฎเชพเช‚ 3 เชตเชฐเซเชท เชฒเชพเช—เซเชฏเชพเช‚ - เช…เชฎเชพเชฐเซ‡ เช•เซเชตเซ‡เชฐเซ€ เชเช•เซเชเชฟเช•เซเชฏเซเชถเชจเชจเชพ เชตเชฟเชตเชฟเชง เชคเชฌเช•เซเช•เชพเชฎเชพเช‚ เช•เซ‹เชกเชจเซ‡ เชซเชฐเซ€เชฅเซ€ เชฒเช–เชตเซ‹ เชชเชกเซเชฏเซ‹. PostgreSQL 9.6 เช เช•เซ‹เชกเชจเซ‡ เชตเชงเซ เชธเซเชงเชพเชฐเชตเชพ เชฎเชพเชŸเซ‡ เชˆเชจเซเชซเซเชฐเชพเชธเซเชŸเซเชฐเช•เซเชšเชฐ เชฐเชœเซ‚ เช•เชฐเซเชฏเซเช‚. เช…เชจเซเช—เชพเชฎเซ€ เชธเช‚เชธเซเช•เชฐเชฃเซ‹เชฎเชพเช‚, เช…เชจเซเชฏ เชชเซเชฐเช•เชพเชฐเชจเซ€ เช•เซเชตเซ‡เชฐเซ€ เชธเชฎเชพเช‚เชคเชฐ เชฐเซ€เชคเซ‡ เชšเชฒเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡.

เชชเซเชฐเชคเชฟเชฌเช‚เชงเซ‹

  • เชœเซ‹ เชฌเชงเชพ เช•เซ‹เชฐเซ‹ เชชเชนเซ‡เชฒเซ‡เชฅเซ€ เชตเซเชฏเชธเซเชค เชนเซ‹เชฏ เชคเซ‹ เชธเชฎเชพเช‚เชคเชฐ เช…เชฎเชฒเชจเซ‡ เชธเช•เซเชทเชฎ เช•เชฐเชถเซ‹ เชจเชนเซ€เช‚, เช…เชจเซเชฏเชฅเชพ เช…เชจเซเชฏ เชตเชฟเชจเช‚เชคเซ€เช“ เชงเซ€เชฎเซ€ เชฅเชˆ เชœเชถเซ‡.
  • เชธเซŒเชฅเซ€ เช…เช—เชคเซเชฏเชจเซเช‚, เช‰เชšเซเชš WORK_MEM เชฎเซ‚เชฒเซเชฏเซ‹ เชธเชพเชฅเซ‡เชจเซ€ เชธเชฎเชพเช‚เชคเชฐ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพ เช˜เชฃเซ€ เชฌเชงเซ€ เชฎเซ‡เชฎเชฐเซ€เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ‡ เช›เซ‡ - เชฆเชฐเซ‡เช• เชนเซ‡เชถ เชœเซ‹เช‡เชจ เช…เชฅเชตเชพ เชธเซ‰เชฐเซเชŸ work_mem เชฎเซ‡เชฎเชฐเซ€ เชฒเซ‡ เช›เซ‡.
  • เช“เช›เซ€ เชตเชฟเชฒเช‚เชฌเชคเชพ OLTP เช•เซเชตเซ‡เชฐเซ€เชเชจเซ‡ เชธเชฎเชพเช‚เชคเชฐ เช…เชฎเชฒ เชฆเซเชตเชพเชฐเชพ เชเชกเชชเซ€ เช•เชฐเซ€ เชถเช•เชพเชคเซ€ เชจเชฅเซ€. เช…เชจเซ‡ เชœเซ‹ เช•เซเชตเซ‡เชฐเซ€ เชเช• เชชเช‚เช•เซเชคเชฟ เช†เชชเซ‡ เช›เซ‡, เชคเซ‹ เชธเชฎเชพเช‚เชคเชฐ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพ เชฎเชพเชคเซเชฐ เชคเซ‡เชจเซ‡ เชงเซ€เชฎเซเช‚ เช•เชฐเชถเซ‡.
  • เชตเชฟเช•เชพเชธเช•เชฐเซเชคเชพเช“เชจเซ‡ TPC-H เชฌเซ‡เชจเซเชšเชฎเชพเชฐเซเช•เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพเชจเซเช‚ เชชเชธเช‚เชฆ เช›เซ‡. เช•เชฆเชพเชš เชคเชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เชธเช‚เชชเซ‚เชฐเซเชฃ เชธเชฎเชพเช‚เชคเชฐ เช…เชฎเชฒ เชฎเชพเชŸเซ‡ เชธเชฎเชพเชจ เชชเซเชฐเชถเซเชจเซ‹ เช›เซ‡.
  • เชชเซเชฐเชฟเชกเชฟเช•เซ‡เชŸ เชฒเซ‰เช•เชฟเช‚เช— เชตเชฟเชจเชพ เชฎเชพเชคเซเชฐ SELECT เช•เซเชตเซ‡เชฐเซ€เช เชธเชฎเชพเช‚เชคเชฐ เชฐเซ€เชคเซ‡ เชšเชฒเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡.
  • เช•เซ‡เชŸเชฒเซ€เช•เชตเชพเชฐ เชฏเซ‹เช—เซเชฏ เช…เชจเซเช•เซเชฐเชฎเชฃเชฟเช•เชพ เชธเชฎเชพเช‚เชคเชฐ เชฎเซ‹เชกเชฎเชพเช‚ เช•เซเชฐเชฎเชฟเช• เชŸเซ‡เชฌเชฒ เชธเซเช•เซ‡เชจเชฟเช‚เช— เช•เชฐเชคเชพเช‚ เชตเชงเซ เชธเชพเชฐเซ€ เชนเซ‹เชฏ เช›เซ‡.
  • เช•เซเชตเซ‡เชฐเซ€ เชฅเซ‹เชญเชพเชตเชตเซ€ เช…เชจเซ‡ เช•เชฐเซเชธเชฐ เชธเชฎเชฐเซเชฅเชฟเชค เชจเชฅเซ€.
  • เชตเชฟเชจเซเชกเซ‹ เชซเช‚เช•เซเชถเชจเซเชธ เช…เชจเซ‡ เช“เชฐเซเชกเชฐ เช•เชฐเซ‡เชฒ เชธเซ‡เชŸ เชเช—เซเชฐเซ€เช—เซ‡เชŸ เชซเช‚เช•เซเชถเชจเซเชธ เชธเชฎเชพเช‚เชคเชฐ เชจเชฅเซ€.
  • เชคเชฎเซ‡ I/O เชตเชฐเซเช•เชฒเซ‹เชกเชฎเชพเช‚ เช•เช‚เชˆเชชเชฃ เชฎเซ‡เชณเชตเซ€ เชถเช•เชคเชพ เชจเชฅเซ€.
  • เชคเซเชฏเชพเช‚ เช•เซ‹เชˆ เชธเชฎเชพเช‚เชคเชฐ เชธเซ‰เชฐเซเชŸเชฟเช‚เช— เช…เชฒเซเช—เซ‹เชฐเชฟเชงเชฎเซเชธ เชจเชฅเซ€. เชชเชฐเช‚เชคเซ เชธเซ‰เชฐเซเชŸ เชธเชพเชฅเซ‡เชจเชพ เชชเซเชฐเชถเซเชจเซ‹ เช•เซ‡เชŸเชฒเชพเช• เชชเชพเชธเชพเช“เชฎเชพเช‚ เชธเชฎเชพเช‚เชคเชฐ เชฐเซ€เชคเซ‡ เชšเชฒเชพเชตเซ€ เชถเช•เชพเชฏ เช›เซ‡.
  • เชธเชฎเชพเช‚เชคเชฐ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพเชจเซ‡ เชธเช•เซเชทเชฎ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ CTE (WITH...) เชจเซ‡ เชจเซ‡เชธเซเชŸเซ‡เชก SELECT เชธเชพเชฅเซ‡ เชฌเชฆเชฒเซ‹.
  • เชคเซƒเชคเซ€เชฏ-เชชเช•เซเชท เชกเซ‡เชŸเชพ เชฐเซ‡เชชเชฐเซเชธ เชนเชœเซ เชธเซเชงเซ€ เชธเชฎเชพเช‚เชคเชฐ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพเชจเซ‡ เชธเชฎเชฐเซเชฅเชจ เช†เชชเชคเชพ เชจเชฅเซ€ (เชชเชฐเช‚เชคเซ เชคเซ‡เช“ เช•เชฐเซ€ เชถเช•เซ‡ เช›เซ‡!)
  • เชธเช‚เชชเซ‚เชฐเซเชฃ เชฌเชนเชพเชฐ เชœเซ‹เช‡เชจ เชธเชชเซ‹เชฐเซเชŸเซ‡เชก เชจเชฅเซ€.
  • max_rows เชธเชฎเชพเช‚เชคเชฐ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพเชจเซ‡ เช…เช•เซเชทเชฎ เช•เชฐเซ‡ เช›เซ‡.
  • เชœเซ‹ เช•เซเชตเซ‡เชฐเซ€เชจเซเช‚ เชซเช‚เช•เซเชถเชจ เชนเซ‹เชฏ เช•เซ‡ เชœเซ‡เชจเซ‡ PARALLEL SAFE เชคเชฐเซ€เช•เซ‡ เชšเชฟเชนเซเชจเชฟเชค เชจ เช•เชฐเซเชฏเซเช‚ เชนเซ‹เชฏ, เชคเซ‹ เชคเซ‡ เชธเชฟเช‚เช—เชฒ เชฅเซเชฐเซ‡เชกเซ‡เชก เชนเชถเซ‡.
  • เชธเซ€เชฐเซ€เชฏเชฒเชพเช‡เชเซ‡เชฌเชฒ เชŸเซเชฐเชพเชจเซเชเซ‡เช•เซเชถเชจ เช†เช‡เชธเซ‹เชฒเซ‡เชถเชจ เชฒเซ‡เชตเชฒ เชธเชฎเชพเช‚เชคเชฐ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพเชจเซ‡ เช…เช•เซเชทเชฎ เช•เชฐเซ‡ เช›เซ‡.

เชชเชฐเซ€เช•เซเชทเชฃ เชตเชพเชคเชพเชตเชฐเชฃ

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

เชธเชฎเชพเช‚เชคเชฐ เชเช•เชคเซเชฐเซ€เช•เชฐเชฃ

เชธเชฎเชพเช‚เชคเชฐ เชธเซ‡เช• เชธเซเช•เซ‡เชจ เชจเซ‹เชก เช†เช‚เชถเชฟเช• เชเช•เชคเซเชฐเซ€เช•เชฐเชฃ เชฎเชพเชŸเซ‡ เชชเช‚เช•เซเชคเชฟเช“ เชฌเชจเชพเชตเซ‡ เช›เซ‡. "เช†เช‚เชถเชฟเช• เชเช•เช‚เชฆเชฐ" เชจเซ‹เชก เช† เชฐเซ‡เช–เชพเช“เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เชŸเซเชฐเชฟเชฎ เช•เชฐเซ‡ เช›เซ‡ 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 เชฅเซ€). เชชเซ‹เชธเซเชŸเช—เซเชฐเซ‡เชเชธเช•เซเชฏเซเชเชฒเชจเชพ เช…เชจเซเชฏ เชญเชพเช—เซ‹ เชฅเซเชฐเซ‡เชกเซ‹เชจเซ‡ เชฌเชฆเชฒเซ‡ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพเช“เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ‡ เช›เซ‡, เชคเซ‡เชฅเซ€ 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 เชฎเชพเช‚ เชตเชฟเชญเชพเช—เซ‹ เชฆเซเชตเชพเชฐเชพ เชœเซ‹เชกเชพเชฃ เชกเชฟเชซเซ‰เชฒเซเชŸ เชฐเซ‚เชชเซ‡ เช…เช•เซเชทเชฎ: เชคเซ‡ เช–เซ‚เชฌ เช–เชฐเซเชšเชพเชณ เชธเชฎเชฏเชชเชคเซเชฐเช• เชงเชฐเชพเชตเซ‡ เช›เซ‡. เชธเชฎเชพเชจ เชชเชพเชฐเซเชŸเซ€เชถเชจ เชธเชพเชฅเซ‡เชจเชพ เช•เซ‹เชทเซเชŸเช•เซ‹เชจเซ‡ เชชเชพเชฐเซเชŸเซ€เชถเชจ เชฆเซเชตเชพเชฐเชพ เชชเชพเชฐเซเชŸเซ€เชถเชจเชฎเชพเช‚ เชœเซ‹เชกเซ€ เชถเช•เชพเชฏ เช›เซ‡. เช† เชฐเซ€เชคเซ‡ 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)

เชฎเซเช–เซเชฏ เชตเชธเซเชคเซ เช เช›เซ‡ เช•เซ‡ เชตเชฟเชญเชพเช—เซ‹เชฎเชพเช‚ เชœเซ‹เชกเชพเชฃ เชธเชฎเชพเช‚เชคเชฐ เช›เซ‡ เชœเซ‹ เช† เชตเชฟเชญเชพเช—เซ‹ เชชเซ‚เชฐเชคเชพ เชชเซเชฐเชฎเชพเชฃเชฎเชพเช‚ เชฎเซ‹เชŸเชพ เชนเซ‹เชฏ.

เชธเชฎเชพเช‚เชคเชฐ เชเชชเซ‡เชจเซเชก

เชธเชฎเชพเช‚เชคเชฐ เชเชชเซ‡เชจเซเชก เชตเชฟเชตเชฟเชง เชตเชฐเซเช•เชซเซเชฒเซ‹เชฎเชพเช‚ เชตเชฟเชตเชฟเชง เชฌเซเชฒเซ‹เช•เซเชธเชจเซ‡ เชฌเชฆเชฒเซ‡ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€ เชถเช•เชพเชฏ เช›เซ‡. เช† เชธเชพเชฎเชพเชจเซเชฏ เชฐเซ€เชคเซ‡ เชฏเซเชจเชฟเชฏเชจ เชคเชฎเชพเชฎ เชชเซเชฐเชถเซเชจเซ‹ เชธเชพเชฅเซ‡ เชฅเชพเชฏ เช›เซ‡. เช—เซ‡เชฐเชฒเชพเชญ เช เช“เช›เซ€ เชธเชฎเชพเชจเชคเชพ เช›เซ‡, เช•เชพเชฐเชฃ เช•เซ‡ เชฆเชฐเซ‡เช• เช•เชพเชฐเซเชฏเช•เชฐ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพ เชฎเชพเชคเซเชฐ 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

เชเช• เชŸเชฟเชชเซเชชเชฃเซ€ เช‰เชฎเซ‡เชฐเซ‹