ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½Π° Π°Π½Π°Π»ΠΈΡ‚ΠΈΠΊΠ° Π² микросСрвисната Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°: Π΄Π° ΠΏΠΎΠΌΠΎΠ³Π½Π΅ΠΌ ΠΈ Π΄Π° подскаТСм Postgres FDW

ΠœΠΈΠΊΡ€ΠΎΡΠ΅Ρ€Π²ΠΈΡΠ½Π°Ρ‚Π° Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°, ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎ Π½Π° всичко останало Π² Ρ‚ΠΎΠ·ΠΈ свят, ΠΈΠΌΠ° своитС прСдимства ΠΈ Π½Π΅Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ†ΠΈ. Някои процСси стават ΠΏΠΎ-прости, Π° Π΄Ρ€ΡƒΠ³ΠΈ β€” ΠΏΠΎ-слоТни. Π’ ΠΈΠΌΠ΅Ρ‚ΠΎ Π½Π° Π±ΡŠΡ€Π·ΠΈΠ½Π°Ρ‚Π° Π½Π° ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈΡ‚Π΅ ΠΈ ΠΏΠΎ-Π΄ΠΎΠ±Ρ€Π°Ρ‚Π° мащабируСмост трябва Π΄Π° ΠΏΡ€Π°Π²ΠΈΠΌ ΠΆΠ΅Ρ€Ρ‚Π²ΠΈ. Π•Π΄Π½Π° ΠΎΡ‚ тях Π΅ услоТняванСто Π½Π° Π°Π½Π°Π»ΠΈΡ‚ΠΈΠΊΠ°Ρ‚Π°. Π”ΠΎΠΊΠ°Ρ‚ΠΎ ΠΏΡ€ΠΈ ΠΌΠΎΠ½ΠΎΠ»ΠΈΡ‚Π° цялата ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½Π° Π°Π½Π°Π»ΠΈΡ‚ΠΈΠΊΠ° ΠΌΠΎΠΆΠ΅ Π΄Π° сС свСдС Π΄ΠΎ SQL заявки към Π°Π½Π°Π»ΠΈΡ‚ΠΈΡ‡Π½Π° Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°, Π² мултисСрвисната Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π° всСки сСрвис Ρ€Π°Π·ΠΏΠΎΠ»Π°Π³Π° със своя Π±Π°Π·Π° ΠΈ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π°, Ρ‡Π΅ с Π΅Π΄Π½Π° заявка Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° сС справим (ΠΈΠ»ΠΈ ΠΌΠΎΠΆΠ΅ Π±ΠΈ ΠΌΠΎΠΆΠ΅ΠΌ?). Π—Π° Ρ‚Π΅Π·ΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ сС интСрСсуват ΠΊΠ°ΠΊ Ρ€Π΅ΡˆΠΈΡ…ΠΌΠ΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° с ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½Π°Ρ‚Π° Π°Π½Π°Π»ΠΈΡ‚ΠΈΠΊΠ° Π² Π½Π°ΡˆΠ°Ρ‚Π° компания ΠΈ ΠΊΠ°ΠΊ сС Π½Π°ΡƒΡ‡ΠΈΡ…ΠΌΠ΅ Π΄Π° ΠΆΠΈΠ²Π΅Π΅ΠΌ с Ρ‚ΠΎΠ²Π° Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ β€” Π΄ΠΎΠ±Ρ€Π΅ дошли.

ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½Π° Π°Π½Π°Π»ΠΈΡ‚ΠΈΠΊΠ° Π² микросСрвисната Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°: Π΄Π° ΠΏΠΎΠΌΠΎΠ³Π½Π΅ΠΌ ΠΈ Π΄Π° подскаТСм Postgres FDW
Казвам сС ПавСл Биваш ΠΈ Π² Π”ΠΎΠΌΠšΠ»ΠΈΠΊ работя Π² Π΅ΠΊΠΈΠΏ, ΠΎΡ‚Π³ΠΎΠ²ΠΎΡ€Π΅Π½ Π·Π° ΠΏΠΎΠ΄Π΄Ρ€ΡŠΠΆΠΊΠ°Ρ‚Π° Π½Π° Π°Π½Π°Π»ΠΈΡ‚ΠΈΡ‡Π½ΠΎΡ‚ΠΎ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ Π½Π° Π΄Π°Π½Π½ΠΈ. Условно Π½Π°ΡˆΠ°Ρ‚Π° дСйност ΠΌΠΎΠΆΠ΅ Π΄Π° сС отнСсС към Π΄Π°Ρ‚Π° ΠΈΠ½ΠΆΠ΅Π½Π΅Ρ€ΠΈΠ½Π³, Π½ΠΎ Π²ΡΡŠΡ‰Π½ΠΎΡΡ‚ ΠΎΠ±Ρ…Π²Π°Ρ‚ΡŠΡ‚ Π½Π° Π·Π°Π΄Π°Ρ‡ΠΈΡ‚Π΅ Π΅ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎ-ΡˆΠΈΡ€ΠΎΠΊ. Има стандартни Π·Π° Π΄Π°Ρ‚Π° ΠΈΠ½ΠΆΠ΅Π½Π΅Ρ€ΠΈΠ½Π³Π° ETL/ELT, ΠΏΠΎΠ΄Π΄Ρ€ΡŠΠΆΠΊΠ° ΠΈ адаптация Π½Π° инструмСнти Π·Π° Π°Π½Π°Π»ΠΈΠ· Π½Π° Π΄Π°Π½Π½ΠΈ ΠΈ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° собствСни инструмСнти. По-ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎ, Π·Π° ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½Π°Ρ‚Π° отчСтност Ρ€Π΅ΡˆΠΈΡ…ΠΌΠ΅ Π΄Π° β€žΡΠ΅ ΠΏΡ€Π°Π²ΠΈΠΌβ€œ, Ρ‡Π΅ ΠΈΠΌΠ°ΠΌΠ΅ ΠΌΠΎΠ½ΠΎΠ»ΠΈΡ‚ ΠΈ Π΄Π° Π΄Π°Π΄Π΅ΠΌ Π½Π° Π°Π½Π°Π»ΠΈΡ‚ΠΈΡ†ΠΈΡ‚Π΅ Π΅Π΄Π½Π° Π±Π°Π·Π°, Π² която Ρ‰Π΅ сС ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Ρ‚ всички Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΈ ΠΈΠΌ Π΄Π°Π½Π½ΠΈ.

Π’ΡŠΠ² всСки случай, Ρ€Π°Π·Π³Π»Π΅ΠΆΠ΄Π°Ρ…ΠΌΠ΅ Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ ΠΎΠΏΡ†ΠΈΠΈ. МоТСшС Π΄Π° ΠΈΠ·Π³Ρ€Π°Π΄ΠΈΠΌ ΠΏΡŠΠ»Π½ΠΎΡ†Π΅Π½Π½ΠΎ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ β€” Π΄ΠΎΡ€ΠΈ ΠΎΠΏΠΈΡ‚Π°Ρ…ΠΌΠ΅, Π½ΠΎ, чСстно ΠΊΠ°Π·Π°Π½ΠΎ, Π½Π΅ успяхмС Π΄Π° синхронизирамС Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π½ΠΎ чСститС ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ Π² Π»ΠΎΠ³ΠΈΠΊΠ°Ρ‚Π° с относитСлно бавния процСс Π½Π° ΠΈΠ·Π³Ρ€Π°ΠΆΠ΄Π°Π½Π΅ Π½Π° Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅Ρ‚ΠΎ ΠΈ внасянСто Π½Π° ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ Π² Π½Π΅Π³ΠΎ (Π°ΠΊΠΎ Π½Π° някого Π΅ успяло, моля, Π½Π°ΠΏΠΈΡˆΠ΅Ρ‚Π΅ Π² ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΡ‚Π΅ ΠΊΠ°ΠΊ). МоТСшС Π΄Π° ΠΊΠ°ΠΆΠ΅ΠΌ Π½Π° Π°Π½Π°Π»ΠΈΡ‚ΠΈΡ†ΠΈΡ‚Π΅: β€žΠ₯Π΅ΠΉ, Π½Π°ΡƒΡ‡Π΅Ρ‚Π΅ python ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅Ρ‚Π΅ с Π°Π½Π°Π»ΠΈΡ‚ΠΈΡ‡Π½ΠΈ Ρ€Π΅ΠΏΠ»ΠΈΠΊΠΈβ€œ, Π½ΠΎ Ρ‚ΠΎΠ²Π° Π΅ Π΄ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π½ΠΎ изискванС Π·Π° ΠΏΠΎΠ΄Π±ΠΎΡ€ Π½Π° пСрсонал, ΠΈ Π½ΠΈ сС ΡΡ‚Ρ€ΡƒΠ²Π°ΡˆΠ΅, Ρ‡Π΅ Π΅ ΠΏΠΎ-Π΄ΠΎΠ±Ρ€Π΅ Π΄Π° Π³ΠΎ ΠΈΠ·Π±Π΅Π³Π½Π΅ΠΌ, Π°ΠΊΠΎ ΠΌΠΎΠΆΠ΅ΠΌ. Π Π΅ΡˆΠΈΡ…ΠΌΠ΅ Π΄Π° ΠΎΠΏΠΈΡ‚Π°ΠΌΠ΅ тСхнологията FDW (Foreign Data Wrapper): Π²ΡΡŠΡ‰Π½ΠΎΡΡ‚, Ρ‚ΠΎΠ²Π° Π΅ стандартСн dblink, ΠΊΠΎΠΉΡ‚ΠΎ Π΅ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ Π² стандарта SQL, Π½ΠΎ с ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎ-ΡƒΠ΄ΠΎΠ±Π΅Π½ интСрфСйс. На Π±Π°Π·Π°Ρ‚Π° Π½Π° нСя Π½Π°ΠΏΡ€Π°Π²ΠΈΡ…ΠΌΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΠ΅Ρ‚ΠΎ Π² ΠΊΡ€Π°ΠΉΠ½Π° смСтка стана основно ΠΈ Π½Π° Π½Π΅Π³ΠΎ сС спряхмС. ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΡΡ‚ΠΈΡ‚Π΅ ΠΌΡƒ са Ρ‚Π΅ΠΌΠ° Π½Π° ΠΎΡ‚Π΄Π΅Π»Π½Π° статия, Π° ΠΌΠΎΠΆΠ΅ Π±ΠΈ ΠΈ Π½Π° ΠΏΠΎΠ²Π΅Ρ‡Π΅ ΠΎΡ‚ Π΅Π΄Π½Π°, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ искамС Π΄Π° Ρ€Π°Π·ΠΊΠ°ΠΆΠ΅ΠΌ Π·Π° ΠΌΠ½ΠΎΠ³ΠΎ Π½Π΅Ρ‰Π°: ΠΎΡ‚ синхронизацията Π½Π° схСмитС Π½Π° Π±Π°Π·ΠΈΡ‚Π΅ Π΄ΠΎ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° Π΄ΠΎΡΡ‚ΡŠΠΏΠ° ΠΈ анонимизацията Π½Π° Π»ΠΈΡ‡Π½ΠΈΡ‚Π΅ Π΄Π°Π½Π½ΠΈ. Врябва ΡΡŠΡ‰ΠΎ Π΄Π° сС ΡƒΡ‚ΠΎΡ‡Π½ΠΈ, Ρ‡Π΅ Ρ‚ΠΎΠ²Π° Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π½Π΅ Π΅ замСститСл Π½Π° Ρ€Π΅Π°Π»Π½ΠΈΡ‚Π΅ Π°Π½Π°Π»ΠΈΡ‚ΠΈΡ‡Π½ΠΈ Π±Π°Π·ΠΈ ΠΈ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π°, Ρ‚ΠΎ Ρ€Π΅ΡˆΠ°Π²Π° само ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Π° Π·Π°Π΄Π°Ρ‡Π°.

На високо Π½ΠΈΠ²ΠΎ, Ρ‚ΠΎΠ²Π° ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° Ρ‚Π°ΠΊΠ°:

ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½Π° Π°Π½Π°Π»ΠΈΡ‚ΠΈΠΊΠ° Π² микросСрвисната Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°: Π΄Π° ΠΏΠΎΠΌΠΎΠ³Π½Π΅ΠΌ ΠΈ Π΄Π° подскаТСм Postgres FDW
ИмамС Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ PostgreSQL, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΠΈΡ‚Π΅ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π°Ρ‚ своитС Ρ€Π°Π±ΠΎΡ‚Π½ΠΈ Π΄Π°Π½Π½ΠΈ, Π° Π½Π°ΠΉ-Π²Π°ΠΆΠ½ΠΎΡ‚ΠΎ Π΅, Ρ‡Π΅ към Ρ‚Π°Π·ΠΈ Π±Π°Π·Π° Ρ‡Ρ€Π΅Π· FDW са ΡΠ²ΡŠΡ€Π·Π°Π½ΠΈ Π°Π½Π°Π»ΠΈΡ‚ΠΈΡ‡Π½ΠΈ Ρ€Π΅ΠΏΠ»ΠΈΠΊΠΈ Π½Π° всички услуги. Π’ΠΎΠ²Π° Π΄Π°Π²Π° Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ Π΄Π° сС напишС заявка към няколко Π±Π°Π·ΠΈ, Π±Π΅Π· Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΠ°ΠΊΠ²ΠΈ са Ρ‚Π΅: PostgreSQL, MySQL, MongoDB ΠΈΠ»ΠΈ Π½Π΅Ρ‰ΠΎ Π΄Ρ€ΡƒΠ³ΠΎ (Ρ„Π°ΠΉΠ», API, Π°ΠΊΠΎ случайно няма подходящ Π²Ρ€Π°ΠΏΠ΅Ρ€, ΠΌΠΎΠΆΠ΅ Π΄Π° сС напишС свой). Ами, ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° всичко Π΅ Π½Π°Ρ€Π΅Π΄! Π Π°Π·ΠΎΡ‚ΠΈΠ²Π°ΠΌΠ΅ сС?

Ако всичко Π·Π°Π²ΡŠΡ€ΡˆΠ²Π°ΡˆΠ΅ Ρ‚ΠΎΠ»ΠΊΠΎΠ²Π° Π±ΡŠΡ€Π·ΠΎ ΠΈ лСсно, вСроятно нямашС Π΄Π° ΠΈΠΌΠ° ΠΈ статия.

Π’Π°ΠΆΠ½ΠΎ Π΅ ясно Π΄Π° осъзнавамС ΠΊΠ°ΠΊ PostgreSQL ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π²Π° заявкитС към ΠΎΡ‚Π΄Π°Π»Π΅Ρ‡Π΅Π½ΠΈ ΡΡŠΡ€Π²ΡŠΡ€ΠΈ. Π’ΠΎΠ²Π° ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ, Π½ΠΎ чСсто Π½Π΅ ΠΌΡƒ сС ΠΎΠ±Ρ€ΡŠΡ‰Π° Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅: PostgreSQL раздСля заявката Π½Π° части, ΠΊΠΎΠΈΡ‚ΠΎ сС ΠΈΠ·ΠΏΡŠΠ»Π½ΡΠ²Π°Ρ‚ Π½Π° ΠΎΡ‚Π΄Π°Π»Π΅Ρ‡Π΅Π½ΠΈΡ‚Π΅ ΡΡŠΡ€Π²ΡŠΡ€ΠΈ нСзависимо, ΡΡŠΠ±ΠΈΡ€Π° Ρ‚Π΅Π·ΠΈ Π΄Π°Π½Π½ΠΈ, Π° Ρ„ΠΈΠ½Π°Π»Π½ΠΈΡ‚Π΅ изчислСния ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π° сам, слСдоватСлно скоростта Π½Π° изпълнСниС Π½Π° заявката Ρ‰Π΅ зависи Π² Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»Π½Π° стСпСн ΠΎΡ‚ Ρ‚ΠΎΠ²Π° ΠΊΠ°ΠΊ Π΅ написана. Π‘ΡŠΡ‰ΠΎ Ρ‚Π°ΠΊΠ° трябва Π΄Π° сС ΠΎΡ‚Π±Π΅Π»Π΅ΠΆΠΈ: ΠΊΠΎΠ³Π°Ρ‚ΠΎ Π΄Π°Π½Π½ΠΈΡ‚Π΅ ΠΏΠΎΡΡ‚ΡŠΠΏΠ²Π°Ρ‚ ΠΎΡ‚ ΠΎΡ‚Π΄Π°Π»Π΅Ρ‡Π΅Π½ ΡΡŠΡ€Π²ΡŠΡ€, Ρ‚Π΅ Π²Π΅Ρ‡Π΅ нямат индСкси, нямат Π½ΠΈΡ‰ΠΎ, ΠΊΠΎΠ΅Ρ‚ΠΎ Π΄Π° ΠΏΠΎΠ΄ΠΏΠΎΠΌΠΎΠ³Π½Π΅ ΠΏΠ»Π°Π½ΠΈΡ€Π°Ρ‡Π°, слСдоватСлно ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΠΏΠΎΠΌΠΎΠ³Π½Π΅ΠΌ ΠΈ Π΄Π° ΠΌΡƒ подсказвамС само Π½ΠΈΠ΅ самитС. И Ρ‚ΠΎΡ‡Π½ΠΎ Π·Π° Ρ‚ΠΎΠ²Π° искамС Π΄Π° Ρ€Π°Π·ΠΊΠ°ΠΆΠ΅ΠΌ ΠΏΠΎ-ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ.

ΠŸΡ€ΠΎΡΡ‚ Π·Π°ΠΏΠΈΡ‚ ΠΈ ΠΏΠ»Π°Π½ с Π½Π΅Π³ΠΎ

Π—Π° Π΄Π° ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ ΠΊΠ°ΠΊ PostgreSQL изпълнява Π·Π°ΠΏΠΈΡ‚ към Ρ‚Π°Π±Π»ΠΈΡ†Π° с 6 ΠΌΠΈΠ»ΠΈΠΎΠ½Π° Ρ€Π΅Π΄Π° Π½Π° ΠΎΡ‚Π΄Π°Π»Π΅Ρ‡Π΅Π½ ΡΡŠΡ€Π²ΡŠΡ€, Π½Π΅ΠΊΠ° Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ простия ΠΏΠ»Π°Π½.

explain analyze verbose  
SELECT count(1)
FROM fdw_schema.table;

АгрСгат (cost=418383.23..418383.24 rows=1 width=8) (actual time=3857.198..3857.198 rows=1 loops=1)
  Π˜Π·Ρ…ΠΎΠ΄: count(1)
  ->  Π’ΡŠΠ½ΡˆΠ½ΠΎ сканиранС Π½Π° fdw_schema."table"  (cost=100.00..402376.14 rows=6402838 width=0) (actual time=4.874..3256.511 rows=6406868 loops=1)
        Π˜Π·Ρ…ΠΎΠ΄: "table".id, "table".is_active, "table".meta, "table".created_dt
        ΠžΡ‚Π΄Π°Π»Π΅Ρ‡Π΅Π½ SQL: SELECT NULL FROM fdw_schema.table
Π’Ρ€Π΅ΠΌΠ΅ Π·Π° ΠΏΠ»Π°Π½ΠΈΡ€Π°Π½Π΅: 0.986 ms
Π’Ρ€Π΅ΠΌΠ΅ Π·Π° изпълнСниС: 3857.436 ms

Π˜Π·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° инструкцята VERBOSE позволява Π΄Π° Π²ΠΈΠ΄ΠΈΠΌ Π·Π°ΠΏΠΈΡ‚Π°, ΠΊΠΎΠΉΡ‚ΠΎ Ρ‰Π΅ бъдС ΠΈΠ·ΠΏΡ€Π°Ρ‚Π΅Π½ Π½Π° отдалСчСния ΡΡŠΡ€Π²ΡŠΡ€ ΠΈ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΠΈΡ‚Π΅, ΠΊΠΎΠΈΡ‚ΠΎ Ρ‰Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ Π·Π° ΠΏΠΎ-Π½Π°Ρ‚Π°Ρ‚ΡŠΡˆΠ½Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° (Ρ€Π΅Π΄ΠΈΡ†Π° RemoteSQL).

НСка ΠΎΡ‚ΠΈΠ΄Π΅ΠΌ ΠΌΠ°Π»ΠΊΠΎ ΠΏΠΎ-Π΄Π°Π»Π΅Ρ‡ ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π² нашия Π·Π°ΠΏΠΈΡ‚ нСсколько Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ: Π΅Π΄ΠΈΠ½ ΠΏΠΎ Π±ΡƒΠ»Π΅Π² ΠΏΠΎΠ»Π΅Ρ‚ΠΎ, Π΅Π΄ΠΈΠ½ ΠΏΠΎ ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Π½ΠΈΠ΅ timestamp Π² ΠΈΠ½Ρ‚Π΅Ρ€Π²Π°Π» ΠΈ Π΅Π΄ΠΈΠ½ ΠΏΠΎ jsonb.

explain analyze verbose
SELECT count(1)
FROM fdw_schema.table 
WHERE is_active is True
AND created_dt BETWEEN CURRENT_DATE - INTERVAL '7 month' 
AND CURRENT_DATE - INTERVAL '6 month'
AND meta->>'source' = 'test';

АгрСгат (cost=577487.69..577487.70 rows=1 width=8) (actual time=27473.818..25473.819 rows=1 loops=1)
  Π˜Π·Ρ…ΠΎΠ΄: count(1)
  ->  Π’ΡŠΠ½ΡˆΠ½ΠΎ сканиранС Π½Π° fdw_schema."table"  (cost=100.00..577469.21 rows=7390 width=0) (actual time=31.369..25372.466 rows=1360025 loops=1)
        Π˜Π·Ρ…ΠΎΠ΄: "table".id, "table".is_active, "table".meta, "table".created_dt
        Π€ΠΈΠ»Ρ‚ΡŠΡ€: (("table".is_active IS TRUE) AND (("table".meta ->> 'source'::text) = 'test'::text) AND ("table".created_dt >= (('now'::cstring)::date - '7 mons'::interval)) AND ("table".created_dt <= ((('now'::cstring)::date)::timestamp with time zone - '6 mons'::interval)))
        Π Π΅Π΄ΠΎΠ²Π΅ отстранСни ΠΎΡ‚ Ρ„ΠΈΠ»Ρ‚ΡŠΡ€Π°: 5046843
        ΠžΡ‚Π΄Π°Π»Π΅Ρ‡Π΅Π½ SQL: SELECT created_dt, is_active, meta FROM fdw_schema.table
Π’Ρ€Π΅ΠΌΠ΅ Π·Π° ΠΏΠ»Π°Π½ΠΈΡ€Π°Π½Π΅: 0.665 ms
Π’Ρ€Π΅ΠΌΠ΅ Π·Π° изпълнСниС: 27474.118 ms

Π’ΡƒΠΊ ΠΈΠΌΠ΅Π½Π½ΠΎ сС ΠΊΡ€ΠΈΠ΅ ΠΌΠΎΠΌΠ΅Π½Ρ‚ΡŠΡ‚, Π½Π° ΠΊΠΎΠΉΡ‚ΠΎ трябва Π΄Π° ΠΎΠ±ΡŠΡ€Π½Π΅ΠΌ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ ΠΏΡ€ΠΈ написванСто Π½Π° запроси. Π€ΠΈΠ»Ρ‚Ρ€ΠΈΡ‚Π΅ Π½Π΅ бяха ΠΏΡ€Π΅Π΄Π°Π΄Π΅Π½ΠΈ Π½Π° отдалСчСния ΡΡŠΡ€Π²ΡŠΡ€, ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π²Π°, Ρ‡Π΅ PostgreSQL ΠΈΠ·Π²Π»ΠΈΡ‡Π° всичкитС 6 ΠΌΠΈΠ»ΠΈΠΎΠ½Π° Ρ€Π΅Π΄Π°, Π·Π° Π΄Π° ΠΌΠΎΠΆΠ΅ слСд Ρ‚ΠΎΠ²Π° Π»ΠΎΠΊΠ°Π»Π½ΠΎ Π΄Π° Π³ΠΈ Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ€Π° (Ρ€Π΅Π΄ΠΈΡ†Π° Filter) ΠΈ Π΄Π° ΠΈΠ·Π²ΡŠΡ€ΡˆΠΈ агрСгация. Π£ΡΠΏΠ΅Ρ…ΡŠΡ‚ зависи ΠΎΡ‚ Ρ‚ΠΎΠ²Π° Π΄Π° напишСм Π·Π°ΠΏΠΈΡ‚ Ρ‚Π°ΠΊΠ°, Ρ‡Π΅ Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ‚Π΅ Π΄Π° сС ΠΏΡ€Π΅Π΄Π°Π²Π°Ρ‚ Π½Π° ΠΎΡ‚Π΄Π°Π»Π΅Ρ‡Π΅Π½Π°Ρ‚Π° машина, Π° Π½ΠΈΠ΅ Π΄Π° ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°ΠΌΠ΅ ΠΈ Π°Π³Ρ€Π΅Π³ΠΈΡ‚ΠΈΡ€Π°ΠΌΠ΅ само Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΈΡ‚Π΅ Ρ€Π΅Π΄ΠΎΠ²Π΅.

Π’ΠΎΠ²Π° Π΅ някаква глупост

Π‘ boolean ΠΏΠΎΠ»Π΅Ρ‚Π° β€” всичко Π΅ просто. ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΡŠΡ‚ Π² оригиналния Π·Π°ΠΏΠΈΡ‚ възникна ΠΏΠΎΡ€Π°Π΄ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° ΠΈ. Ако Π³ΠΎ Π·Π°ΠΌΠ΅Π½ΠΈΠΌ с =, Ρ‚ΠΎΠ³Π°Π²Π° Ρ‰Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ слСдния Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚:

ΠΎΠ±ΡŠΡΡΠ½ΠΈΡ‚Π΅ Π°Π½Π°Π»ΠΈΠ· Π² подробностях
SELECT count(1)
FROM fdw_schema.table
WHERE is_active = True
AND created_dt BETWEEN CURRENT_DATE - INTERVAL '7 month' 
AND CURRENT_DATE - INTERVAL '6 month'
AND meta->>'source' = 'test';

АгрСгат (ΡΡ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ=508010.14..508010.15 строки=1 ΡˆΠΈΡ€ΠΈΠ½Π°=8) (фактичСскоС врСмя=19064.314..19064.314 строки=1 Ρ†ΠΈΠΊΠ»Ρ‹=1)
  Π’Ρ‹Π²ΠΎΠ΄: count(1)
  ->  Π˜Π½ΠΎΡΡ‚Ρ€Π°Π½Π½ΠΎΠ΅ сканированиС Π½Π° fdw_schema."table" (ΡΡ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ=100.00..507988.44 строки=8679 ΡˆΠΈΡ€ΠΈΠ½Π°=0) (фактичСскоС врСмя=33.035..18951.278 строки=1360025 Ρ†ΠΈΠΊΠ»Ρ‹=1)
        Π’Ρ‹Π²ΠΎΠ΄: "table".id, "table".is_active, "table".meta, "table".created_dt
        Π€ΠΈΠ»ΡŒΡ‚Ρ€: ((("table".meta ->> 'source'::text) = 'test'::text) AND ("table".created_dt >= (('now'::cstring)::date - '7 mons'::interval)) AND ("table".created_dt <= ((('now'::cstring)::date)::timestamp with time zone - '6 mons'::interval)))
        Π£Π΄Π°Π»Π΅Π½Π½Ρ‹Π΅ строки Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠΌ: 3567989
        Π£Π΄Π°Π»Π΅Π½Π½Ρ‹ΠΉ SQL: SELECT created_dt, meta FROM fdw_schema.table WHERE (is_active)
ВрСмя планирования: 0.834 мс
ВрСмя выполнСния: 19064.534 мс

Как Π²ΠΈΠ΄ΠΈΡ‚Π΅, Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ Π±Ρ‹Π» ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½ Π½Π° ΡƒΠ΄Π°Π»Ρ‘Π½Π½Ρ‹ΠΉ сСрвСр, Π° врСмя выполнСния ΡΠΎΠΊΡ€Π°Ρ‚ΠΈΠ»ΠΎΡΡŒ с 27 Π΄ΠΎ 19 сСкунд.

Π‘Ρ‚ΠΎΠΈΡ‚ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ ΠΈ отличаСтся ΠΎΡ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° = Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ ΡƒΠΌΠ΅Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ со Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ Null. Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ is not True Π² Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π΅ оставит значСния False ΠΈ Null, Ρ‚ΠΎΠ³Π΄Π° ΠΊΠ°ΠΊ != True оставит Ρ‚ΠΎΠ»ΡŒΠΊΠΎ значСния False. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΠΏΡ€ΠΈ Π·Π°ΠΌΠ΅Π½Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° is not слСдуСт ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π² Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ Π΄Π²Π° условия с ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠΌ OR, ΠΊ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ, WHERE (col != True) OR (col is null).

Π‘ boolean Ρ€Π°Π·ΠΎΠ±Ρ€Π°Π»ΠΈΡΡŒ, двигаСмся дальшС. А ΠΏΠΎΠΊΠ° Π²Π΅Ρ€Π½Π΅ΠΌ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ ΠΏΠΎ Π±ΡƒΠ»Π΅Π²ΠΎΠΌΡƒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ Π² ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½Ρ‹ΠΉ Π²ΠΈΠ΄, Ρ‡Ρ‚ΠΎΠ±Ρ‹ нСзависимо Ρ€Π°ΡΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ эффСкт ΠΎΡ‚ Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ.

timestamptz? hz

Π’ΠΎΠΎΠ±Ρ‰Π΅, часто приходится ΡΠΊΡΠΏΠ΅Ρ€ΠΈΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ с Ρ‚Π΅ΠΌ, ΠΊΠ°ΠΊ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ запрос, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΡƒΡ‡Π°ΡΡ‚Π²ΡƒΡŽΡ‚ ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹Π΅ сСрвСры, Π° ΡƒΠΆΠ΅ ΠΏΠΎΡ‚ΠΎΠΌ ΠΈΡΠΊΠ°Ρ‚ΡŒ объяснСниС, ΠΏΠΎΡ‡Π΅ΠΌΡƒ происходит ΠΈΠΌΠ΅Π½Π½ΠΎ Ρ‚Π°ΠΊ. ΠžΡ‡Π΅Π½ΡŒ ΠΌΠ°Π»ΠΎ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΏΠΎ этому ΠΏΠΎΠ²ΠΎΠ΄Ρƒ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ Π² Π˜Π½Ρ‚Π΅Ρ€Π½Π΅Ρ‚Π΅. Π’Π°ΠΊ, Π² экспСримСнтах ΠΌΡ‹ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΠ»ΠΈ, Ρ‡Ρ‚ΠΎ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ ΠΏΠΎ фиксированной Π΄Π°Ρ‚Π΅ ΡƒΠ»Π΅Ρ‚Π°Π΅Ρ‚ Π½Π° ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹ΠΉ сСрвСр Π½Π° ΡƒΡ€Π°, Π° Π²ΠΎΡ‚ ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ Π·Π°Π΄Π°Ρ‚ΡŒ Π΄Π°Ρ‚Ρƒ динамичСски, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, now() ΠΈΠ»ΠΈ CURRENT_DATE, Ρ‚Π°ΠΊΠΎΠ³ΠΎ Π½Π΅ происходит. Π’ нашСм ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅, ΠΌΡ‹ Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ Ρ‚Π°ΠΊΠΎΠΉ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€, Ρ‡Ρ‚ΠΎΠ±Ρ‹ столбСц created_at содСрТал Π² сСбС Π΄Π°Π½Π½Ρ‹Π΅ Ρ€ΠΎΠ²Π½ΠΎ Π·Π° 1 мСсяц Π² ΠΏΡ€ΠΎΡˆΠ»ΠΎΠΌ (BETWEEN CURRENT_DATE - INTERVAL β€˜7 month’ AND CURRENT_DATE - INTERVAL β€˜6 month’). Π§Ρ‚ΠΎ ΠΆΠ΅ ΠΌΡ‹ прСдприняли Π² Π΄Π°Π½Π½ΠΎΠΌ случаС?

ΠΎΠ±ΡŠΡΡΠ½ΠΈΡ‚ΡŒ Π°Π½Π°Π»ΠΈΠ· ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Ρ‹ΠΉ
SELECT count(1)
FROM fdw_schema.table 
WHERE is_active is True
AND created_dt >= (SELECT CURRENT_DATE::timestamptz - INTERVAL '7 month') 
AND created_dt >'source' = 'test';

АгрСгат (cost=306875.17..306875.18 rows=1 width=8) (фактичСскоС врСмя=4789.114..4789.115 rows=1 loops=1)
  Π’Ρ‹Π²ΠΎΠ΄: count(1)
  InitPlan 1 (Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ $0)
    ->  Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ (cost=0.00..0.02 rows=1 width=8) (фактичСскоС врСмя=0.007..0.008 rows=1 loops=1)
          Π’Ρ‹Π²ΠΎΠ΄: ((('now'::cstring)::date)::timestamp with time zone - '7 mons'::interval)
  InitPlan 2 (Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ $1)
    ->  Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ (cost=0.00..0.02 rows=1 width=8) (фактичСскоС врСмя=0.002..0.002 rows=1 loops=1)
          Π’Ρ‹Π²ΠΎΠ΄: ((('now'::cstring)::date)::timestamp with time zone - '6 mons'::interval)
  ->  Π˜Π½ΠΎΡΡ‚Ρ€Π°Π½Π½ΠΎΠ΅ сканированиС Π½Π° fdw_schema."table"  (cost=100.02..306874.86 rows=105 width=0) (фактичСскоС врСмя=23.475..4681.419 rows=1360025 loops=1)
        Π’Ρ‹Π²ΠΎΠ΄: "table".id, "table".is_active, "table".meta, "table".created_dt
        Π€ΠΈΠ»ΡŒΡ‚Ρ€: (("table".is_active IS TRUE) И (("table".meta ->> 'source'::text) = 'test'::text))
        Π£Π΄Π°Π»Π΅Π½Π½Ρ‹Π΅ строки Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠΌ: 76934
        Π£Π΄Π°Π»Π΅Π½Π½Ρ‹ΠΉ SQL: SELECT is_active, meta FROM fdw_schema.table WHERE ((created_dt >= $1::timestamp with time zone)) И ((created_dt < $2::timestamp with time zone))
ВрСмя планирования: 0.703 ms
ВрСмя выполнСния: 4789.379 ms

Нам ΡƒΠ΄Π°Π»ΠΎΡΡŒ ΠΏΠΎΠ΄ΡΠΊΠ°Π·Π°Ρ‚ΡŒ ΠΏΠ»Π°Π½ΠΈΡ€ΠΎΠ²Ρ‰ΠΈΠΊΡƒ Π·Π°Ρ€Π°Π½Π΅Π΅ Π²Ρ‹Ρ‡ΠΈΡΠ»ΠΈΡ‚ΡŒ Π΄Π°Ρ‚Ρƒ Π² подзапросС ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ ΡƒΠΆΠ΅ Π³ΠΎΡ‚ΠΎΠ²ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ Π² Ρ„ΠΈΠ»ΡŒΡ‚Ρ€. Π­Ρ‚Π° подсказка Π΄Π°Π»Π° Π½Π°ΠΌ ΠΎΡ‚Π»ΠΈΡ‡Π½Ρ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚, запрос стал быстрСС ΠΏΠΎΡ‡Ρ‚ΠΈ Π² 6 Ρ€Π°Π·!

Π’Π°ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ Π²Π½ΠΈΠΌΠ°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ: Ρ‚ΠΈΠΏ Π΄Π°Π½Π½Ρ‹Ρ… Π² подзапросС Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ полю, ΠΏΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ ΠΌΡ‹ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΡƒΠ΅ΠΌ, ΠΈΠ½Π°Ρ‡Π΅ ΠΏΠ»Π°Π½ΠΈΡ€ΠΎΠ²Ρ‰ΠΈΠΊ Ρ€Π΅ΡˆΠΈΡ‚, Ρ‡Ρ‚ΠΎ Ρ‚ΠΈΠΏΡ‹ Ρ€Π°Π·Π½Ρ‹Π΅, ΠΈ Π±ΡƒΠ΄Π΅Ρ‚ сначала ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ всС Π΄Π°Π½Π½Ρ‹Π΅, Π° Π·Π°Ρ‚Π΅ΠΌ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΡ… локально.

Π’Π΅Ρ€Π½Π΅ΠΌ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ ΠΏΠΎ Π΄Π°Ρ‚Π΅ ΠΊ исходному Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ.

Freddy ΠΏΡ€ΠΎΡ‚ΠΈΠ² Jsonb

Π’ ΠΎΠ±Ρ‰Π΅ΠΌ, Π±ΡƒΠ»Π΅Π²Ρ‹ поля ΠΈ Π΄Π°Ρ‚Ρ‹ ΡƒΠΆΠ΅ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ускорили наш запрос, ΠΎΠ΄Π½Π°ΠΊΠΎ оставался Π΅Ρ‰Π΅ ΠΎΠ΄ΠΈΠ½ Ρ‚ΠΈΠΏ Π΄Π°Π½Π½Ρ‹Ρ…. Π‘ΠΈΡ‚Π²Π° с Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ†ΠΈΠ΅ΠΉ ΠΏΠΎ Π½Π΅ΠΌΡƒ, чСстно говоря, Π΄ΠΎ сих ΠΏΠΎΡ€ Π½Π΅ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π°, хотя ΠΌΡ‹ здСсь добились успСха. Π˜Ρ‚Π°ΠΊ, Π²ΠΎΡ‚ ΠΊΠ°ΠΊ ΡƒΠ΄Π°Π»ΠΎΡΡŒ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ ΠΏΠΎ jsonb полю Π½Π° ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹ΠΉ сСрвСр.

ΠΎΠ±ΡŠΡΡΠ½ΠΈΡ‚ΡŒ Π°Π½Π°Π»ΠΈΠ· ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Ρ‹ΠΉ
SELECT count(1)
FROM fdw_schema.table 
WHERE is_active is True
AND created_dt BETWEEN CURRENT_DATE - INTERVAL '7 month' 
AND CURRENT_DATE - INTERVAL '6 month'
AND meta @> '{"source":"test"}'::jsonb;

АгрСгат (cost=245463.60..245463.61 rows=1 width=8) (фактичСскоС врСмя=6727.589..6727.590 rows=1 loops=1)
  Π’Ρ‹Π²ΠΎΠ΄: count(1)
  ->  Π˜Π½ΠΎΡΡ‚Ρ€Π°Π½Π½ΠΎΠ΅ сканированиС Π½Π° fdw_schema."table"  (cost=1100.00..245459.90 rows=1478 width=0) (фактичСскоС врСмя=16.213..6634.794 rows=1360025 loops=1)
        Π’Ρ‹Π²ΠΎΠ΄: "table".id, "table".is_active, "table".meta, "table".created_dt
        Π€ΠΈΠ»ΡŒΡ‚Ρ€: (("table".is_active IS TRUE) И ("table".created_dt >= (('now'::cstring)::date - '7 mons'::interval)) И ("table".created_dt  '{"source": "test"}'::jsonb))
ВрСмя планирования: 0.747 ms
ВрСмя выполнСния: 6727.815 ms

ВмСсто ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ†ΠΈΠΈ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ наличия ΠΎΠ΄Π½ΠΎΠ³ΠΎ jsonb Π² Π΄Ρ€ΡƒΠ³ΠΎ. 7 сСкунди вмСсто ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»Π½ΠΈΡ‚Π΅ 29. Π’ΠΎΠ²Π° Π΅ СдинствСният ΡƒΡΠΏΠ΅ΡˆΠ΅Π½ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ Π·Π° ΠΏΡ€Π΅Π΄Π°Π²Π°Π½Π΅ Π½Π° Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ ΠΏΠΎ jsonb Π½Π° ΠΎΡ‚Π΄Π°Π»Π΅Π½ ΡΡŠΡ€Π²ΡŠΡ€, Π½ΠΎ Ρ‚ΡƒΠΊ Π΅ Π²Π°ΠΆΠ½ΠΎ Π΄Π° сС Π²Π½ΠΈΠΌΠ°Π²Π° с Π΅Π΄Π½ΠΎ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅: ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ вСрсия Π½Π° Π±Π°Π·Π°Ρ‚Π° 9.6, Π½ΠΎ Π΄ΠΎ края Π½Π° Π°ΠΏΡ€ΠΈΠ» ΠΏΠ»Π°Π½ΠΈΡ€Π°ΠΌΠ΅ Π΄Π° Π·Π°Π²ΡŠΡ€ΡˆΠΈΠΌ послСднитС тСстовС ΠΈ Π΄Π° ΠΏΡ€Π΅ΠΌΠΈΠ½Π΅ΠΌ Π½Π° вСрсия 12. ΠšΠ°Ρ‚ΠΎ сС ΠΎΠ±Π½ΠΎΠ²ΠΈΠΌ, Ρ‰Π΅ напишСм ΠΊΠ°ΠΊ Ρ‚ΠΎΠ²Π° Π΅ повлияло, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ ΠΈΠΌΠ° ΠΌΠ½ΠΎΠ³ΠΎ измСнСния, Π½Π° ΠΊΠΎΠΈΡ‚ΠΎ Ρ€Π°Π·Ρ‡ΠΈΡ‚Π°ΠΌΠ΅: json_path, Π½ΠΎΠ²ΠΎ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ CTE, push down (ΡΡŠΡ‰Π΅ΡΡ‚Π²ΡƒΠ²Π° ΠΎΡ‚ вСрсия 10). Много искамС Π΄Π° ΠΎΠΏΠΈΡ‚Π°ΠΌΠ΅ ΠΊΠΎΠ»ΠΊΠΎΡ‚ΠΎ сС ΠΌΠΎΠΆΠ΅ ΠΏΠΎ-скоро.

Π—Π°Π²ΡŠΡ€ΡˆΠΈ Π³ΠΎ

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ…ΠΌΠ΅ ΠΊΠ°ΠΊ всяка промяна влияС Π½Π° скоростта Π½Π° заявката ΠΏΠΎΠΎΡ‚Π΄Π΅Π»Π½ΠΎ. НСка сСга Π΄Π° Π²ΠΈΠ΄ΠΈΠΌ ΠΊΠ°ΠΊΠ²ΠΎ Ρ‰Π΅ станС, ΠΊΠΎΠ³Π°Ρ‚ΠΎ всичкитС Ρ‚Ρ€ΠΈ Ρ„ΠΈΠ»Ρ‚ΡŠΡ€Π° са написани ΠΏΡ€Π°Π²ΠΈΠ»Π½ΠΎ.

explain analyze verbose
SELECT count(1)
FROM fdw_schema.table 
WHERE is_active = True
AND created_dt >= (SELECT CURRENT_DATE::timestamptz - INTERVAL '7 month') 
AND created_dt  '{"source":"test"}'::jsonb;

Aggregate  (cost=322041.51..322041.52 rows=1 width=8) (actual time=2278.867..2278.867 rows=1 loops=1)
  Output: count(1)
  InitPlan 1 (returns $0)
    ->  Result  (cost=0.00..0.02 rows=1 width=8) (actual time=0.010..0.010 rows=1 loops=1)
          Output: ((('now'::cstring)::date)::timestamp with time zone - '7 mons'::interval)
  InitPlan 2 (returns $1)
    ->  Result  (cost=0.00..0.02 rows=1 width=8) (actual time=0.003..0.003 rows=1 loops=1)
          Output: ((('now'::cstring)::date)::timestamp with time zone - '6 mons'::interval)
  ->  Foreign Scan on fdw_schema."table"  (cost=100.02..322041.41 rows=25 width=0) (actual time=8.597..2153.809 rows=1360025 loops=1)
        Output: "table".id, "table".is_active, "table".meta, "table".created_dt
        Remote SQL: SELECT NULL FROM fdw_schema.table WHERE (is_active) AND ((created_dt >= $1::timestamp with time zone)) AND ((created_dt  '{"source": "test"}'::jsonb))
Planning time: 0.820 ms
Execution time: 2279.087 ms

Π”Π°, заявката ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° ΠΏΠΎ-слоТна, Ρ‚ΠΎΠ²Π° Π΅ Π½Π°Π»ΠΎΠΆΠ΅Π½Π° Ρ†Π΅Π½Π°, Π½ΠΎ скоростта Π½Π° изпълнСниС Π΅ 2 сСкунди, ΠΊΠΎΠ΅Ρ‚ΠΎ Π΅ ΠΏΠΎΠ²Π΅Ρ‡Π΅ ΠΎΡ‚ дСсСт ΠΏΡŠΡ‚ΠΈ ΠΏΠΎ-Π±ΡŠΡ€Π·ΠΎ! И Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ Π·Π° проста заявка към относитСлно малък Π½Π°Π±ΠΎΡ€ ΠΎΡ‚ Π΄Π°Π½Π½ΠΈ. ΠŸΡ€ΠΈ Ρ€Π΅Π°Π»Π½ΠΈ заявки ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°Ρ…ΠΌΠ΅ ΠΏΠ΅Ρ‡Π°Π»Π±Π° ΠΎΡ‚ стотици ΠΏΡŠΡ‚ΠΈ.

Π”Π° ΠΎΠ±ΠΎΠ±Ρ‰ΠΈΠΌ: Π°ΠΊΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ PostgreSQL с FDW, Π²ΠΈΠ½Π°Π³ΠΈ провСрявайтС Π΄Π°Π»ΠΈ всичкитС Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ ΠΎΡ‚ΠΈΠ²Π°Ρ‚ Π½Π° отдалСчСния ΡΡŠΡ€Π²ΡŠΡ€, ΠΈ Ρ‰Π΅ Π±ΡŠΠ΄Π΅Ρ‚Π΅ щастливи… Най-ΠΌΠ°Π»ΠΊΠΎΡ‚ΠΎ, Π΄ΠΎΠΊΠ°Ρ‚ΠΎ Π½Π΅ стигнСтС Π΄ΠΎ Π΄ΠΆΠΎΠΉΠ½Π΅Ρ€ΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ‚Π°Π±Π»ΠΈΡ†ΠΈ ΠΎΡ‚ Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ ΡΡŠΡ€Π²ΡŠΡ€ΠΈ. Но Ρ‚ΠΎΠ²Π° Π΅ история Π·Π° Π΄Ρ€ΡƒΠ³Π° статия.

Благодаря Π·Π° Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅Ρ‚ΠΎ! Π©Π΅ сС Ρ€Π°Π΄Π²Π°ΠΌ Π΄Π° чуя Π²ΡŠΠΏΡ€ΠΎΡΠΈ, ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈ, ΠΊΠ°ΠΊΡ‚ΠΎ ΠΈ истории Π·Π° вашия ΠΎΠΏΠΈΡ‚ Π² ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΡ‚Π΅.

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com

ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС с Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ πŸ”₯ ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС с Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ | ProHoster