αžŸαŸ†αžŽαž½αžšαžŸαŸ’αžšαž”αž‚αŸ’αž“αžΆαž“αŸ…αž€αŸ’αž“αž»αž„ PostgreSQL

αžŸαŸ†αžŽαž½αžšαžŸαŸ’αžšαž”αž‚αŸ’αž“αžΆαž“αŸ…αž€αŸ’αž“αž»αž„ PostgreSQL
αžŸαŸŠαžΈαž—αžΈαž™αžΌαž‘αŸ†αž“αžΎαž”αž˜αžΆαž“αžŸαŸ’αž“αžΌαž›αž…αŸ’αžšαžΎαž“αŸ” αž’αžŸαŸ‹αžšαž™αŸˆαž–αŸαž›αž‡αžΆαž…αŸ’αžšαžΎαž“αž†αŸ’αž“αžΆαŸ† αž€αž˜αŸ’αž˜αžœαž·αž’αžΈαž”αžΆαž“αž“αžΉαž„αž€αŸ†αž–αž»αž„αž•αŸ’αž‰αžΎαžŸαŸ†αžŽαž½αžšαž‘αŸ…αž€αžΆαž“αŸ‹αž˜αžΌαž›αžŠαŸ’αž‹αžΆαž“αž‘αž·αž“αŸ’αž“αž“αŸαž™αžŸαŸ’αžšαž”αž‚αŸ’αž“αžΆαŸ” αž”αŸ’αžšαžŸαž·αž“αž”αžΎαžœαžΆαž‡αžΆαžŸαŸ†αžŽαž½αžšαžšαž”αžΆαž™αž€αžΆαžšαžŽαŸαž“αŸ…αž›αžΎαž‡αž½αžšαž‡αžΆαž…αŸ’αžšαžΎαž“αž€αŸ’αž“αž»αž„αžαžΆαžšαžΆαž„αž˜αž½αž™ αžœαžΆαžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž›αžΏαž“αž‡αžΆαž„αž“αŸ…αž–αŸαž›αž”αŸ’αžšαžΎαžŸαŸŠαžΈαž—αžΈαž™αžΌαž…αŸ’αžšαžΎαž“ αž αžΎαž™ PostgreSQL αž’αžΆαž…αž’αŸ’αžœαžΎαžœαžΆαž”αžΆαž“αžαžΆαŸ†αž„αž–αžΈαž€αŸ†αžŽαŸ‚ 9.6αŸ”

αžœαžΆαžαŸ’αžšαžΌαžœαž…αŸ†αžŽαžΆαž™αž–αŸαž› 3 αž†αŸ’αž“αžΆαŸ†αžŠαžΎαž˜αŸ’αž”αžΈαž’αž“αž»αžœαžαŸ’αžαž˜αž»αžαž„αžΆαžšαžŸαŸ†αžŽαž½αžšαžŸαŸ’αžšαž”αž‚αŸ’αž“αžΆ - αž™αžΎαž„αžαŸ’αžšαžΌαžœαžŸαžšαžŸαŸαžšαž€αžΌαžŠαž‘αžΎαž„αžœαž·αž‰αž“αŸ…αžŠαŸ†αžŽαžΆαž€αŸ‹αž€αžΆαž›αž•αŸ’αžŸαŸαž„αŸ—αž“αŸƒαž€αžΆαžšαž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αžŸαŸ†αžŽαž½αžšαŸ” PostgreSQL 9.6 αž”αžΆαž“αžŽαŸ‚αž“αžΆαŸ†αž αŸαžŠαŸ’αž‹αžΆαžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αžŠαžΎαž˜αŸ’αž”αžΈαž€αŸ‚αž›αž˜αŸ’αž’αž€αžΌαžŠαž”αž“αŸ’αžαŸ‚αž˜αž‘αŸ€αžαŸ” αž“αŸ…αž€αŸ’αž“αž»αž„αž€αŸ†αžŽαŸ‚αž‡αžΆαž”αž“αŸ’αžαž”αž“αŸ’αž‘αžΆαž”αŸ‹ αž”αŸ’αžšαž—αŸαž‘αžŸαŸ†αžŽαž½αžšαž•αŸ’αžŸαŸαž„αž‘αŸ€αžαžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αžŸαŸ’αžšαž”αž‚αŸ’αž“αžΆαŸ”

αž€αžΆαžšαžšαžΉαžαžαŸ’αž”αž·αž

  • αž€αž»αŸ†αž”αžΎαž€αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž”αŸ‰αžΆαžšαŸ‰αžΆαž‘αŸ‚αž› αž”αŸ’αžšαžŸαž·αž“αž”αžΎαžŸαŸ’αž“αžΌαž›αž‘αžΆαŸ†αž„αž’αžŸαŸ‹αž‡αžΆαž”αŸ‹αžšαžœαž›αŸ‹ αž”αžΎαž˜αž·αž“αžŠαžΌαž…αŸ’αž“αŸαŸ‡αž‘αŸαžŸαŸ†αžŽαžΎαž•αŸ’αžŸαŸαž„αž‘αŸ€αžαž“αžΉαž„αžαž™αž…αž»αŸ‡αŸ”
  • αžŸαŸ†αžαžΆαž“αŸ‹αž”αŸ†αž•αž»αž αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž”αŸ‰αžΆαžšαŸ‰αžΆαž‘αŸ‚αž›αž‡αžΆαž˜αž½αž™αž“αžΉαž„αžαž˜αŸ’αž›αŸƒ WORK_MEM αžαŸ’αž–αžŸαŸ‹αž”αŸ’αžšαžΎαž’αž„αŸ’αž‚αž…αž„αž…αžΆαŸ†αž…αŸ’αžšαžΎαž“ - αžšαžΆαž›αŸ‹ hash join ឬ sort αž”αŸ’αžšαžΎαž’αž„αŸ’αž‚αž…αž„αž…αžΆαŸ† work_mem αŸ”
  • αžŸαŸ†αžŽαž½αžš OLTP αž—αžΆαž–αž™αžΊαžαž™αŸ‰αžΆαžœαž‘αžΆαž”αž˜αž·αž“αž’αžΆαž…αž”αž„αŸ’αž€αžΎαž“αž›αŸ’αž”αžΏαž“αžŠαŸ„αž™αž€αžΆαžšαž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αžŸαŸ’αžšαž”αž‚αŸ’αž“αžΆαž”αžΆαž“αž‘αŸαŸ” αž αžΎαž™αž”αŸ’αžšαžŸαž·αž“αž”αžΎαžŸαŸ†αžŽαž½αžšαžαŸ’αžšαž‘αž”αŸ‹αž˜αž½αž™αž‡αž½αžš αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž”αŸ‰αžΆαžšαŸ‰αžΆαž‘αŸ‚αž›αž“αžΉαž„αž’αŸ’αžœαžΎαž±αŸ’αž™αžœαžΆαžαž™αž…αž»αŸ‡αž”αŸ‰αž»αžŽαŸ’αžŽαŸ„αŸ‡αŸ”
  • αž’αŸ’αž“αž€αž’αž—αž·αžœαžŒαŸ’αžαž“αŸαž…αžΌαž›αž…αž·αžαŸ’αžαž”αŸ’αžšαžΎαžŸαŸ’αžαž„αŸ‹αžŠαžΆαžš TPC-H αŸ” αž”αŸ’αžšαž αŸ‚αž›αž‡αžΆαž’αŸ’αž“αž€αž˜αžΆαž“αžŸαŸ†αžŽαž½αžšαžŸαŸ’αžšαžŠαŸ€αž„αž‚αŸ’αž“αžΆαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αž”αŸ‰αžΆαžšαŸ‰αžΆαž‘αŸ‚αž›αžŠαŸαž›αŸ’αž’αž₯αžαžαŸ’αž…αŸ„αŸ‡αŸ”
  • αž˜αžΆαž“αžαŸ‚αžŸαŸ†αžŽαž½αžš SELECT αžŠαŸ„αž™αž‚αŸ’αž˜αžΆαž“αž€αžΆαžšαž…αžΆαž€αŸ‹αžŸαŸ„αž‡αžΆαž˜αž»αž“αž”αŸ‰αž»αžŽαŸ’αžŽαŸ„αŸ‡αžŠαŸ‚αž›αžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αžŸαŸ’αžšαž”αž‚αŸ’αž“αžΆαŸ”
  • αž–αŸαž›αžαŸ’αž›αŸ‡αž€αžΆαžšαž’αŸ’αžœαžΎαž›αž·αž”αž·αž€αŸ’αžšαž˜αžαŸ’αžšαžΉαž˜αžαŸ’αžšαžΌαžœαž‚αžΊαž”αŸ’αžšαžŸαžΎαžšαž‡αžΆαž„αž€αžΆαžšαžŸαŸ’αž€αŸαž“αžαžΆαžšαžΆαž„αž”αž“αŸ’αžαž”αž“αŸ’αž‘αžΆαž”αŸ‹αž‚αŸ’αž“αžΆαž€αŸ’αž“αž»αž„αžšαž”αŸ€αž”αž”αŸ‰αžΆαžšαŸ‰αžΆαž‘αŸ‚αž›αŸ”
  • αž€αžΆαžšαž•αŸ’αž’αžΆαž€αžŸαŸ†αžŽαž½αžš αž“αž·αž„αž‘αžŸαŸ’αžŸαž“αŸαž‘αŸ’αžšαž“αž·αž…αž˜αž·αž“αžαŸ’αžšαžΌαžœαž”αžΆαž“αž‚αžΆαŸ†αž‘αŸ’αžšαž‘αŸαŸ”
  • αž˜αž»αžαž„αžΆαžšβ€‹αž”αž„αŸ’αž’αž½αž… αž“αž·αž„β€‹αž’αž“αž»αž‚αž˜αž“αŸβ€‹αžŸαžšαž»αž”β€‹αžŸαŸ†αžŽαž»αŸ†β€‹αžŠαŸ‚αž›β€‹αž”αžΆαž“β€‹αž”αž‰αŸ’αž‡αžΆβ€‹αž˜αž·αž“β€‹αžŸαŸ’αžšαž”β€‹αž‚αŸ’αž“αžΆβ€‹αž‘αŸαŸ”
  • αž’αŸ’αž“αž€αž˜αž·αž“αž‘αž‘αž½αž›αž”αžΆαž“αž’αŸ’αžœαžΈαž“αŸ…αž€αŸ’αž“αž»αž„αž”αž“αŸ’αž‘αž»αž€αž€αžΆαžšαž„αžΆαžš I/O αž‘αŸαŸ”
  • αž˜αž·αž“αž˜αžΆαž“αž€αŸ’αž”αž½αž“αžŠαŸ„αŸ‡αžŸαŸ’αžšαžΆαž™αž€αžΆαžšαžαž˜αŸ’αžšαŸ€αž”αžŸαŸ’αžšαž”αž‚αŸ’αž“αžΆαž‘αŸαŸ” αž”αŸ‰αž»αž“αŸ’αžαŸ‚αžŸαŸ†αžŽαž½αžšαžŠαŸ‚αž›αž˜αžΆαž“αž”αŸ’αžšαž—αŸαž‘αž’αžΆαž…αžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αžŸαŸ’αžšαž”αž‚αŸ’αž“αžΆαž€αŸ’αž“αž»αž„αž‘αž·αžŠαŸ’αž‹αž—αžΆαž–αž˜αž½αž™αž…αŸ†αž“αž½αž“αŸ”
  • αž‡αŸ†αž“αž½αžŸ CTE (αž‡αžΆαž˜αž½αž™ ... ) αž‡αžΆαž˜αž½αž™ SELECT αžŠαŸ‚αž›αžαŸ’αžšαžΌαžœαž”αžΆαž“αž—αŸ’αž‡αžΆαž”αŸ‹αžŠαžΎαž˜αŸ’αž”αžΈαž”αžΎαž€αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž”αŸ‰αžΆαžšαŸ‰αžΆαž‘αŸ‚αž›αŸ”
  • αž§αž”αž€αžšαžŽαŸαžšαž»αŸ†αž‘αž·αž“αŸ’αž“αž“αŸαž™αž—αžΆαž‚αžΈαž‘αžΈαž”αžΈαž˜αž·αž“αž‘αžΆαž“αŸ‹αž‚αžΆαŸ†αž‘αŸ’αžšαžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž”αŸ‰αžΆαžšαŸ‰αžΆαž‘αŸ‚αž›αž“αŸ…αž‘αžΎαž™αž‘αŸ (αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž–αž½αž€αž‚αŸαž’αžΆαž…!)
  • αž€αžΆαžšβ€‹αž…αžΌαž›αžšαž½αž˜β€‹αž–αŸαž‰β€‹αž›αŸαž‰β€‹αž˜αž·αž“β€‹αžαŸ’αžšαžΌαžœβ€‹αž”αžΆαž“β€‹αž‚αžΆαŸ†αž‘αŸ’αžšβ€‹αž‘αŸαŸ”
  • max_rows αž”αž·αž‘αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž”αŸ‰αžΆαžšαŸ‰αžΆαž‘αŸ‚αž›αŸ”
  • αž”αŸ’αžšαžŸαž·αž“αž”αžΎαžŸαŸ†αžŽαž½αžšαž˜αž½αž™αž˜αžΆαž“αž˜αž»αžαž„αžΆαžšαžŠαŸ‚αž›αž˜αž·αž“αžαŸ’αžšαžΌαžœαž”αžΆαž“αžŸαž˜αŸ’αž‚αžΆαž›αŸ‹αžαžΆ PARALLEL SAFE αž“αŸ„αŸ‡αžœαžΆαž“αžΉαž„αžαŸ’αžšαžΌαžœαž”αžΆαž“αžŠαžΆαž€αŸ‹αž‡αžΆαžαŸ’αžŸαŸ‚αžαŸ‚αž˜αž½αž™αŸ”
  • αž€αž˜αŸ’αžšαž·αžαž―αž€αŸ„αž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αž€αžΆαžš 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 . αž…αž„αž€αŸ’αžšαž„αž€αžΌαžŠαžŠαŸ„αž™αž”αŸ’αžšαžΎαž–αžΆαž€αŸ’αž™αž”αž‰αŸ’αž‡αžΆ make αŸ”
  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 cores αž‡αžΆαž…αŸ’αžšαžΎαž“αŸ” αž“αŸ…αž€αŸ’αž“αž»αž„αž”αŸ’αžšαž–αŸαž“αŸ’αž’αž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αž€αžΆαžšαž‘αŸ†αž“αžΎαž” αž―αž€αžŸαžΆαžšαž‘αž·αž“αŸ’αž“αž“αŸαž™ PostgreSQL αžαŸ’αžšαžΌαžœαž”αžΆαž“αžšαž€αŸ’αžŸαžΆαž‘αž»αž€αž™αŸ‰αžΆαž„αž›αŸ’αž’αŸ” αž‡αžΆαž˜αž½αž™αž“αžΉαž„αž€αžΆαžšαž’αžΆαž“αž‡αžΆαž˜αž»αž“ αžœαžΆαž’αžΆαž…αž‘αŸ…αžšαž½αž…αžŠαžΎαž˜αŸ’αž”αžΈαž‘αž‘αž½αž›αž”αžΆαž“αž”αŸ’αž›αž»αž€αž’αŸ†αž‡αžΆαž„αž–αžΈαž€αžΆαžšαž•αŸ’αž‘αž»αž€αž‡αžΆαž„αžŸαŸ†αžŽαžΎ PG daemon αŸ” αžŠαžΌαž…αŸ’αž“αŸαŸ‡ αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαžŸαŸ†αžŽαž½αžšαž˜αž·αž“αž€αŸ†αžŽαžαŸ‹αžŠαŸ„αž™αžŒαžΈαžŸ 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

αž€αžΆαžšαžŸαŸ’αž€αŸαž“αžαžΆαž˜αž›αŸ†αžŠαžΆαž”αŸ‹αž›αŸ†αžŠαŸ„αž™αž”αž„αŸ’αž€αžΎαžαž‡αž½αžšαž…αŸ’αžšαžΎαž“αž–αŸαž€αžŠαŸ„αž™αž‚αŸ’αž˜αžΆαž“αž€αžΆαžšαž”αŸ’αžšαž˜αžΌαž›αž•αŸ’αžαž»αŸ† αžŠαžΌαž…αŸ’αž“αŸαŸ‡αžŸαŸ†αžŽαž½αžšαžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αžŠαŸ„αž™αžŸαŸ’αž“αžΌαž›αžŸαŸŠαžΈαž—αžΈαž™αžΌαžαŸ‚αž˜αž½αž™αŸ”

αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž’αŸ’αž“αž€αž”αž“αŸ’αžαŸ‚αž˜ 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

αž€αžΆαžšαž”αŸ’αžšαž˜αžΌαž›αž•αŸ’αžαž»αŸ†αž”αŸ‰αžΆαžšαŸ‰αžΆαž‘αŸ‚αž›

αžαŸ’αž“αžΆαŸ†αž„ Parallel Seq Scan αž”αž„αŸ’αž€αžΎαžαž‡αž½αžšαžŠαŸαž€αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαž”αŸ’αžšαž˜αžΌαž›αž•αŸ’αžαž»αŸ†αžŠαŸ„αž™αž•αŸ’αž“αŸ‚αž€αŸ” αžαŸ’αž“αžΆαŸ†αž„ "αž€αžΆαžšαž”αŸ’αžšαž˜αžΌαž›αž•αŸ’αžαž»αŸ†αžŠαŸ„αž™αž•αŸ’αž“αŸ‚αž€" αž€αžΆαžαŸ‹αž”αž“αŸ’αž‘αžΆαžαŸ‹αž‘αžΆαŸ†αž„αž“αŸαŸ‡αžŠαŸ„αž™αž”αŸ’αžšαžΎ SUM(). αž“αŸ…αž…αž»αž„αž”αž‰αŸ’αž…αž”αŸ‹ αž”αž‰αŸ’αž‡αžš SUM αž–αžΈαžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž€αž˜αŸ’αž˜αž€αžšαž“αž·αž˜αž½αž™αŸ—αžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αŸ’αžšαž˜αžΌαž›αžŠαŸ„αž™αžαŸ’αž“αžΆαŸ†αž„ "Gather" αŸ”

αž›αž‘αŸ’αž’αž•αž›αž…αž»αž„αž€αŸ’αžšαŸ„αž™αžαŸ’αžšαžΌαžœαž”αžΆαž“αž‚αžŽαž“αžΆαžŠαŸ„αž™αžαŸ’αž“αžΆαŸ†αž„ "αž”αž‰αŸ’αž…αž”αŸ‹αžŸαžšαž»αž”" αŸ” αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž’αŸ’αž“αž€αž˜αžΆαž“αž˜αž»αžαž„αžΆαžšαž”αŸ’αžšαž˜αžΌαž›αž•αŸ’αžαž»αŸ†αž•αŸ’αž‘αžΆαž›αŸ‹αžαŸ’αž›αž½αž“αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€ αž€αž»αŸ†αž—αŸ’αž›αŸαž…αžŸαž˜αŸ’αž‚αžΆαž›αŸ‹αž–αž½αž€αžœαžΆαž‡αžΆ "αžŸαž»αžœαžαŸ’αžαž·αž—αžΆαž–αžŸαŸ’αžšαž”αž‚αŸ’αž“αžΆ"αŸ”

αž…αŸ†αž“αž½αž“αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαžšαž”αžŸαŸ‹αž€αž˜αŸ’αž˜αž€αžš

αž…αŸ†αž“αž½αž“αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαžšαž”αžŸαŸ‹αž€αž˜αŸ’αž˜αž€αžšαž’αžΆαž…αž€αžΎαž“αž‘αžΎαž„αžŠαŸ„αž™αž˜αž·αž“αž…αžΆαŸ†αž”αžΆαž…αŸ‹αž…αžΆαž”αŸ‹αž•αŸ’αžαžΎαž˜αž˜αŸ‰αžΆαžŸαŸŠαžΈαž“αž˜αŸαž‘αžΎαž„αžœαž·αž‰αŸ–

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 αž‡αž½αžš: αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αŸ†αž αž»αžŸ αž“αž·αž„αžŸαž˜αŸ’αžšαžΆαž”αŸ‹ tuples αŸ”

αžαžΎαžαŸ’αžšαžΌαžœαž€αžΆαžšαž›αŸ†αž αžΌαžšαž€αžΆαžšαž„αžΆαžšαž”αŸ‰αž»αž“αŸ’αž˜αžΆαž“?

αžŠαŸ‚αž“αž€αŸ†αžŽαžαŸ‹αž’αž”αŸ’αž”αž”αžšαž˜αžΆαžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αž‰αŸ’αž‡αžΆαž€αŸ‹αžŠαŸ„αž™αž”αŸ‰αžΆαžšαŸ‰αžΆαž˜αŸ‰αŸ‚αžαŸ’αžš 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αŸ– αž€αžΆαžšαž”αŸ’αžšαžΆαžŸαŸ’αžšαŸαž™αž‘αžΆαž€αŸ‹αž‘αž„αžšαžœαžΆαž„αž’αŸ’αž“αž€αžŠαžΉαž€αž“αžΆαŸ† αž“αž·αž„αž€αž˜αŸ’αž˜αž€αžšαž’αžΆαž…αžαŸ’αžšαžΌαžœαž”αžΆαž“αž–αž“αŸ’αž™αžΆαžšαž–αŸαž›αžαžΆαž˜αžŸαž˜αžΆαž˜αžΆαžαŸ’αžšαž‘αŸ…αž“αžΉαž„αž…αŸ†αž“αž½αž“αž“αŸƒ tuples αž–αžΈαžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž€αžΆαžšαž„αžΆαžšαŸ” αž”αŸ‰αžΆαžšαŸ‰αžΆαž˜αŸ‰αŸ‚αžαŸ’αžšαž“αŸαŸ‡αž‚αžŽαž“αžΆαžαž˜αŸ’αž›αŸƒαž“αŸƒαž€αžΆαžšαž•αŸ’αž›αžΆαžŸαŸ‹αž”αŸ’αžαžΌαžšαž‘αž·αž“αŸ’αž“αž“αŸαž™αŸ”

Nested Loop Joins

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 αž‚αžΊαž‡αžΆαž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αž€αžΆαžšαžŸαŸ’αžšαž”αž‚αŸ’αž“αžΆαŸ” Parallel Index Only Scan αžαŸ’αžšαžΌαžœαž”αžΆαž“αžŽαŸ‚αž“αžΆαŸ†αžαŸ‚αž“αŸ…αž€αŸ’αž“αž»αž„αž€αŸ†αžŽαŸ‚ 10αŸ” αžœαžΆαžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαžŸαŸ’αžšαžŠαŸ€αž„αž“αžΉαž„αž€αžΆαžšαžŸαŸ’αž€αŸαž“αžŸαŸ€αžšαŸ€αž›αž”αŸ‰αžΆαžšαŸ‰αžΆαž‘αŸ‚αž›αŸ” αž›αž€αŸ’αžαžαžŽαŸ’αžŒ c_custkey = o_custkey αž’αžΆαž“αž€αžΆαžšαž”αž‰αŸ’αž‡αžΆαž‘αž·αž‰αž˜αž½αž™αž€αŸ’αž“αž»αž„αž˜αž½αž™αž‡αž½αžšαž’αžαž·αžαž·αž‡αž“αŸ” αžŠαžΌαž…αŸ’αž“αŸαŸ‡αžœαžΆαž˜αž·αž“αžŸαŸ’αžšαž”αž‚αŸ’αž“αžΆαž‘αŸαŸ”

Hash αž…αžΌαž›αžšαž½αž˜

αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαžšαž”αžŸαŸ‹αž€αž˜αŸ’αž˜αž€αžšαž“αž·αž˜αž½αž™αŸ—αž”αž„αŸ’αž€αžΎαžαžαžΆαžšαžΆαž„ hash αž•αŸ’αž‘αžΆαž›αŸ‹αžαŸ’αž›αž½αž“αžšαž αžΌαžαžŠαž›αŸ‹ PostgreSQL 11. αž αžΎαž™αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž˜αžΆαž“αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž›αžΎαžŸαž–αžΈαž”αž½αž“αž“αŸαŸ‡ αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž“αžΉαž„αž˜αž·αž“αž”αŸ’αžšαžŸαžΎαžšαž‘αžΎαž„αž‘αŸαŸ” αž“αŸ…αž€αŸ’αž“αž»αž„αž€αŸ†αžŽαŸ‚αžαŸ’αž˜αžΈ αžαžΆαžšαžΆαž„ hash αžαŸ’αžšαžΌαžœαž”αžΆαž“αž…αŸ‚αž€αžšαŸ†αž›αŸ‚αž€αŸ” αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž€αž˜αŸ’αž˜αž€αžšαž“αž·αž˜αž½αž™αŸ—αž’αžΆαž…αž”αŸ’αžšαžΎ 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

αžŸαŸ†αžŽαž½αžšαž‘αžΈ 12 αž–αžΈ TPC-H αž”αž„αŸ’αž αžΆαž‰αž™αŸ‰αžΆαž„αž…αŸ’αž”αžΆαžŸαŸ‹αž“αžΌαžœαž€αžΆαžšαž—αŸ’αž‡αžΆαž”αŸ‹αžŸαž‰αŸ’αž‰αžΆαž”αŸ‰αžΆαžšαŸ‰αžΆαž‘αŸ‚αž›αŸ” αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž€αž˜αŸ’αž˜αž€αžšαž“αž·αž˜αž½αž™αŸ—αžšαž½αž˜αž…αŸ†αžŽαŸ‚αž€αžŠαž›αŸ‹αž€αžΆαžšαž”αž„αŸ’αž€αžΎαžαžαžΆαžšαžΆαž„αžŸαž‰αŸ’αž‰αžΆαžšαž½αž˜αž˜αž½αž™αŸ”

αž”αž‰αŸ’αž…αžΌαž›αž…αžΌαž›αž‚αŸ’αž“αžΆ

αž€αžΆαžšαžšαž½αž˜αž”αž‰αŸ’αž…αžΌαž›αž‚αŸ’αž“αžΆαž“αŸƒαž€αžΆαžšαžšαž½αž˜αž”αž‰αŸ’αž…αžΌαž›αž‚αŸ’αž“αžΆαž‚αžΊαž˜αž·αž“αžŸαŸ’αžšαž”αž‚αŸ’αž“αžΆαž“αŸ…αž€αŸ’αž“αž»αž„αž’αž˜αŸ’αž˜αž‡αžΆαžαž·αŸ” αž€αž»αŸ†αž”αžΆαžšαž˜αŸ’αž—αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž“αŸαŸ‡αž‡αžΆαž‡αŸ†αž αžΆαž“αž…αž»αž„αž€αŸ’αžšαŸ„αž™αž“αŸƒαžŸαŸ†αžŽαž½αžš - αžœαžΆαž“αŸ…αžαŸ‚αž’αžΆαž…αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαžŸαŸ’αžšαž”αž‚αŸ’αž“αžΆαŸ”

-- 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)

αžαŸ’αž“αžΆαŸ†αž„ "αž”αž‰αŸ’αž…αžΌαž›αž‚αŸ’αž“αžΆ" αž˜αžΆαž“αž‘αžΈαžαžΆαŸ†αž„αž“αŸ…αžαžΆαž„αž›αžΎ "αž”αŸ’αžšαž˜αžΌαž›αž•αŸ’αžαž»αŸ†αž”αž‰αŸ’αž…αžΌαž›αž‚αŸ’αž“αžΆ" αŸ” αžŠαžΌαž…αŸ’αž“αŸαŸ‡αž€αžΆαžšαžšαž½αž˜αž”αž‰αŸ’αž…αžΌαž›αž‚αŸ’αž“αžΆαž˜αž·αž“αž”αŸ’αžšαžΎαžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž”αŸ‰αžΆαžšαŸ‰αžΆαž‘αŸ‚αž›αž‘αŸαŸ” αž”αŸ‰αž»αž“αŸ’αžαŸ‚αžαŸ’αž“αžΆαŸ†αž„ "Parallel Index Scan" αž“αŸ…αžαŸ‚αž‡αž½αž™αž‡αžΆαž˜αž½αž™αž•αŸ’αž“αŸ‚αž€αž“αŸαŸ‡αŸ” part_pkey.

αž€αžΆαžšαžαž—αŸ’αž‡αžΆαž”αŸ‹αžαžΆαž˜αž•αŸ’αž“αŸ‚αž€

αž“αŸ…αž€αŸ’αž“αž»αž„ PostgreSQL 11 αž€αžΆαžšαžαž—αŸ’αž‡αžΆαž”αŸ‹αžαžΆαž˜αž•αŸ’αž“αŸ‚αž€ αž”αž·αž‘αžαžΆαž˜αž›αŸ†αž“αžΆαŸ†αžŠαžΎαž˜αŸ– αžœαžΆαž˜αžΆαž“αž€αžΆαž›αžœαž·αž—αžΆαž‚αžαŸ’αž›αŸƒαžŽαžΆαžŸαŸ‹αŸ” αžαžΆαžšαžΆαž„αžŠαŸ‚αž›αž˜αžΆαž“αž—αžΆαž‚αžαžΆαžŸαžŸαŸ’αžšαžŠαŸ€αž„αž‚αŸ’αž“αžΆαž’αžΆαž…αžαŸ’αžšαžΌαžœαž”αžΆαž“αž—αŸ’αž‡αžΆαž”αŸ‹αž‚αŸ’αž“αžΆαžŠαŸ„αž™αž—αžΆαž‚αžαžΆαžŸαŸ” αžœαž·αž’αžΈαž“αŸαŸ‡ Postgres αž“αžΉαž„αž”αŸ’αžšαžΎαžαžΆαžšαžΆαž„ hash αžαžΌαž…αž‡αžΆαž„αŸ” αž€αžΆαžšαž—αŸ’αž‡αžΆαž”αŸ‹αž‚αŸ’αž“αžΆαž“αŸƒαž•αŸ’αž“αŸ‚αž€αž’αžΆαž…αžŸαŸ’αžšαž”αž‚αŸ’αž“αžΆαŸ”

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 αŸ” αž‚αž»αžŽαžœαž·αž”αžαŸ’αžαž·β€‹αž‚αžΊβ€‹αž—αžΆαž–β€‹αžŸαŸ’αžšαž”αž‚αŸ’αž“αžΆβ€‹αžαž·αž…β€‹αž–αŸ’αžšαŸ„αŸ‡β€‹αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšβ€‹αžšαž”αžŸαŸ‹β€‹αž€αž˜αŸ’αž˜αž€αžšβ€‹αž“αž·αž˜αž½αž™αŸ—β€‹αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšβ€‹αžαŸ‚β€‹αŸ‘β€‹αžŸαŸ†αžŽαžΎβ€‹αž”αŸ‰αž»αžŽαŸ’αžŽαŸ„αŸ‡αŸ”

αž˜αžΆαž“αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž€αž˜αŸ’αž˜αž€αžšαž…αŸ†αž“αž½αž“ 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 - αž€αŸ‚αžαž˜αŸ’αžšαžΌαžœαž…αŸ†αž“αž½αž“αžŸαžšαž»αž”αž“αŸƒαžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαžšαž”αžŸαŸ‹αž€αž˜αŸ’αž˜αž€αžšαž‘αŸ…αž“αžΉαž„αž…αŸ†αž“αž½αž“αžŸαŸ’αž“αžΌαž›αžŸαŸŠαžΈαž—αžΈαž™αžΌαž“αŸ…αž›αžΎαž˜αŸ‰αžΆαžŸαŸŠαžΈαž“αž˜αŸαŸ”
  • max_parallel_workers - αžŠαžΌαž…αž‚αŸ’αž“αžΆ αž”αŸ‰αž»αž“αŸ’αžαŸ‚αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž€αžΆαžšαž„αžΆαžšαžŸαŸ’αžšαž”αž‚αŸ’αž“αžΆαŸ”

αž›αž‘αŸ’αž’αž•αž›

αž…αžΆαž”αŸ‹αž–αžΈαž€αŸ†αžŽαŸ‚ 9.6 αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž”αŸ‰αžΆαžšαŸ‰αžΆαž‘αŸ‚αž›αž’αžΆαž…αž’αŸ’αžœαžΎαž±αŸ’αž™αž”αŸ’αžšαžŸαžΎαžšαž‘αžΎαž„αž™αŸ‰αžΆαž„αžαŸ’αž›αžΆαŸ†αž„αž“αžΌαžœαžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž“αŸƒαžŸαŸ†αžŽαž½αžšαžŸαŸ’αž˜αž»αž‚αžŸαŸ’αž˜αžΆαž‰αžŠαŸ‚αž›αžŸαŸ’αž€αŸαž“αž‡αž½αžšαž¬αž›αž·αž”αž·αž€αŸ’αžšαž˜αž‡αžΆαž…αŸ’αžšαžΎαž“αŸ” αž“αŸ…αž€αŸ’αž“αž»αž„ PostgreSQL 10 αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž”αŸ‰αžΆαžšαŸ‰αžΆαž‘αŸ‚αž›αžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αžΎαž€αžαžΆαž˜αž›αŸ†αž“αžΆαŸ†αžŠαžΎαž˜αŸ” αž…αž„αž…αžΆαŸ†αžαžΆαžαŸ’αžšαžΌαžœαž”αž·αž‘αžœαžΆαž“αŸ…αž›αžΎαž˜αŸ‰αžΆαžŸαŸŠαžΈαž“αž˜αŸαžŠαŸ‚αž›αž˜αžΆαž“αž”αž“αŸ’αž‘αž»αž€αž€αžΆαžšαž„αžΆαžš OLTP αž’αŸ†αŸ” αž€αžΆαžšαžŸαŸ’αž€αŸαž“αžαžΆαž˜αž›αŸ†αžŠαžΆαž”αŸ‹αž›αŸ†αžŠαŸ„αž™ αž¬αž€αžΆαžšαžŸαŸ’αž€αŸαž“αž›αž·αž”αž·αž€αŸ’αžšαž˜αž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹αž’αž“αž’αžΆαž“αž…αŸ’αžšαžΎαž“αŸ” αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž’αŸ’αž“αž€αž˜αž·αž“αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαžšαž”αžΆαž™αž€αžΆαžšαžŽαŸαž›αžΎαžŸαŸ†αžŽαž»αŸ†αž‘αž·αž“αŸ’αž“αž“αŸαž™αž‘αžΆαŸ†αž„αž˜αžΌαž›αž‘αŸ αž’αŸ’αž“αž€αž’αžΆαž…αž€αŸ‚αž›αž˜αŸ’αž’αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαžŸαŸ†αžŽαž½αžšαžŠαŸ„αž™αž‚αŸ’αžšαžΆαž“αŸ‹αžαŸ‚αž”αž“αŸ’αžαŸ‚αž˜αž›αž·αž”αž·αž€αŸ’αžšαž˜αžŠαŸ‚αž›αž”αžΆαžαŸ‹ αž¬αž”αŸ’αžšαžΎαž€αžΆαžšαž”αŸ‚αž„αž…αŸ‚αž€αžαŸ’αžšαžΉαž˜αžαŸ’αžšαžΌαžœαŸ”

αžŸαŸαž…αž€αŸ’αžαžΈαž™αŸ„αž„

αž”αŸ’αžšαž—αž–: www.habr.com

αž”αž“αŸ’αžαŸ‚αž˜αž˜αžαž·αž™αŸ„αž”αž›αŸ‹