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

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

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

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

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

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

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

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

ΠŸΡ€ΠΎΡΡ‚ заявка ΠΈ ΠΏΠ»Π°Π½ с Π½Π΅Π³ΠΎ

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

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

Aggregate  (cost=418383.23..418383.24 rows=1 width=8) (actual time=3857.198..3857.198 rows=1 loops=1)
  Output: count(1)
  ->  Foreign Scan on fdw_schema."table"  (cost=100.00..402376.14 rows=6402838 width=0) (actual time=4.874..3256.511 rows=6406868 loops=1)
        Output: "table".id, "table".is_active, "table".meta, "table".created_dt
        Remote SQL: SELECT NULL FROM fdw_schema.table
Planning time: 0.986 ms
Execution time: 3857.436 ms

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

НСка ΠΏΡ€ΠΎΠ΄ΡŠΠ»ΠΆΠΈΠΌ ΠΌΠ°Π»ΠΊΠΎ Π½Π°ΠΏΡ€Π΅Π΄ ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ към Π½Π°ΡˆΠ°Ρ‚Π° заявка няколко Ρ„ΠΈΠ»Ρ‚ΡŠΡ€Π°: Π΅Π΄ΠΈΠ½ ΠΏΠΎ boolean ΠΏΠΎΠ»Π΅, Π΅Π΄ΠΈΠ½ ΠΏΠΎ Π²Ρ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅Ρ‚ΠΎ 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';

Aggregate  (cost=577487.69..577487.70 rows=1 width=8) (actual time=27473.818..25473.819 rows=1 loops=1)
  Output: count(1)
  ->  Foreign Scan on fdw_schema."table"  (cost=100.00..577469.21 rows=7390 width=0) (actual time=31.369..25372.466 rows=1360025 loops=1)
        Output: "table".id, "table".is_active, "table".meta, "table".created_dt
        Filter: (("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)))
        Rows Removed by Filter: 5046843
        Remote SQL: SELECT created_dt, is_active, meta FROM fdw_schema.table
Planning time: 0.665 ms
Execution time: 27474.118 ms

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

That’s some booleanshit

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

обясни Π°Π½Π°Π»ΠΈΠ· ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ
Π˜Π—Π‘Π•Π Π˜ count(1)
Π˜Π— fdw_schema.table
Π“Π”Π• is_active = True
И created_dt ΠœΠ•Π–Π”Π£ Π’Π•ΠšΠ£Π©ΠΠ―_ДАВА - Π˜ΠΠ’Π•Π Π’ΠΠ› '7 мСс'
И Π’Π•ΠšΠ£Π©ΠΠ―_ДАВА - Π˜ΠΠ’Π•Π Π’ΠΠ› '6 мСс'
И 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) И ("table".created_dt >= (('now'::cstring)::date - '7 мСс'::ΠΈΠ½Ρ‚Π΅Ρ€Π²Π°Π»)) И ("table".created_dt <= ((('now'::cstring)::date)::timestamp с Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π·ΠΎΠ½ΠΎΠΉ - '6 мСс'::ΠΈΠ½Ρ‚Π΅Ρ€Π²Π°Π»)))
        Π£Π΄Π°Π»Π΅Π½Π½Ρ‹Π΅ строки: 3567989
        Π£Π΄Π°Π»Π΅Π½Π½Ρ‹ΠΉ SQL: Π˜Π—Π‘Π•Π Π˜ created_dt, meta Π˜Π— fdw_schema.table Π“Π”Π• (is_active)
ВрСмя планирования: 0.834 мс
ВрСмя выполнСния: 19064.534 мс

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

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

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

timestamptz? hz

Π’ΠΎΠΎΠ±Ρ‰Π΅, часто приходится ΡΠΊΡΠΏΠ΅Ρ€ΠΈΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ с Ρ‚Π΅ΠΌ, ΠΊΠ°ΠΊ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ запрос, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΡƒΡ‡Π°ΡΡ‚Π²ΡƒΡŽΡ‚ ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹Π΅ сСрвСра, Π° ΠΏΠΎΡ‚ΠΎΠΌ ΠΈΡΠΊΠ°Ρ‚ΡŒ объяснСниС, ΠΏΠΎΡ‡Π΅ΠΌΡƒ это происходит ΠΈΠΌΠ΅Π½Π½ΠΎ Ρ‚Π°ΠΊ. ΠžΡ‡Π΅Π½ΡŒ ΠΌΠ°Π»ΠΎ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΏΠΎ этому ΠΏΠΎΠ²ΠΎΠ΄Ρƒ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ Π² Π˜Π½Ρ‚Π΅Ρ€Π½Π΅Ρ‚Π΅. Π’ Ρ…ΠΎΠ΄Π΅ экспСримСнтов ΠΌΡ‹ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΠ»ΠΈ, Ρ‡Ρ‚ΠΎ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ ΠΏΠΎ фиксированной Π΄Π°Ρ‚Π΅ ΠΏΡ€ΠΎΡ…ΠΎΠ΄ΠΈΡ‚ Π½Π° ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹ΠΉ сСрвСр Π±Π΅Π· ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ, Π½ΠΎ ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ пытаСмся Π·Π°Π΄Π°Ρ‚ΡŒ Π΄Π°Ρ‚Ρƒ динамичСски, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, now() ΠΈΠ»ΠΈ CURRENT_DATE, этого Π½Π΅ происходит. Π’ нашСм ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΌΡ‹ Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ Ρ‚Π°ΠΊΠΎΠΉ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€, Ρ‡Ρ‚ΠΎΠ±Ρ‹ столбСц created_at содСрТал Π΄Π°Π½Π½Ρ‹Π΅ Ρ€ΠΎΠ²Π½ΠΎ Π·Π° 1 мСсяц Π½Π°Π·Π°Π΄ (ΠœΠ•Π–Π”Π£ Π’Π•ΠšΠ£Π©ΠΠ―_ДАВА β€” Π˜ΠΠ’Π•Π Π’ΠΠ› '7 мСс' И Π’Π•ΠšΠ£Π©ΠΠ―_ДАВА β€” Π˜ΠΠ’Π•Π Π’ΠΠ› '6 мСс'). Π§Ρ‚ΠΎ ΠΆΠ΅ ΠΌΡ‹ прСдприняли Π² Π΄Π°Π½Π½ΠΎΠΌ случаС?

ΠΎΠ±ΡŠΡΡΠ½ΠΈΡ‚ΡŒ Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ
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';

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

НиС подсказахмС Π½Π° ΠΏΠ»Π°Π½ΠΈΡ€ΠΎΠ²Ρ‡ΠΈΠΊΠ° ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»Π½ΠΎ Π΄Π° изчисли Π΄Π°Ρ‚Π°Ρ‚Π° Π² подзапроса ΠΈ Π΄Π° ΠΏΡ€Π΅Π΄Π°Π΄Π΅ Π³ΠΎΡ‚ΠΎΠ²Π°Ρ‚Π° ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π° Π² Ρ„ΠΈΠ»ΡŒΡ‚ΡŠΡ€Π°. И Ρ‚Π°Π·ΠΈ подсказка Π½ΠΈ Π΄Π°Π΄Π΅ прСкрасСн Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚, заявката стана ΠΏΠΎΡ‡Ρ‚ΠΈ 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;

АгрСгат  (ΡΡ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ=245463.60..245463.61 строки=1 ΡˆΠΈΡ€ΠΈΠ½Π°=8) (фактичСскоС врСмя=6727.589..6727.590 строки=1 Ρ†ΠΈΠΊΠ»Ρ‹=1)
  Π’Ρ‹Π²ΠΎΠ΄: count(1)
  ->  Π˜Π½ΠΎΡΡ‚Ρ€Π°Π½Π΅Π½ скан Π½Π° fdw_schema."table"  (ΡΡ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ=1100.00..245459.90 строки=1478 ΡˆΠΈΡ€ΠΈΠ½Π°=0) (фактичСскоС Π²Ρ€Π΅ΠΌΠ΅=16.213..6634.794 строки=1360025 Ρ†ΠΈΠΊΠ»ΠΈ=1)
        Π’Ρ‹Π²ΠΎΠ΄: "table".id, "table".is_active, "table".meta, "table".created_dt
        Π€ΠΈΠ»Ρ‚ΡŠΡ€: (("table".is_active IS TRUE) AND ("table".created_dt >= (('сСга'::cstring)::date - '7 мСсСца'::ΠΈΠ½Ρ‚Π΅Ρ€Π²Π°Π»)) AND ("table".created_dt  '{"source": "test"}'::jsonb))
Π’Ρ€Π΅ΠΌΠ΅ Π·Π° ΠΏΠ»Π°Π½ΠΈΡ€Π°Π½Π΅: 0.747 мс
Π’Ρ€Π΅ΠΌΠ΅ Π·Π° изпълнСниС: 6727.815 мс

ВмСсто ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΈΡ‚Π΅ Π·Π° Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ€Π°Π½Π΅ трябва Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ Π½Π° Π½Π°Π»ΠΈΡ‡ΠΈΠ΅Ρ‚ΠΎ Π½Π° Π΅Π΄ΠΈΠ½ 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 months') 
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 months'::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 months'::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 сСкунди, ΠΊΠΎΠ΅Ρ‚ΠΎ Π΅ ΠΏΠΎΠ²Π΅Ρ‡Π΅ ΠΎΡ‚ 10 ΠΏΡŠΡ‚ΠΈ ΠΏΠΎ-Π±ΡŠΡ€Π·ΠΎ! И Ρ‚ΡƒΠΊ Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ Π·Π° просто Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅ към относитСлно малък Π½Π°Π±ΠΎΡ€ ΠΎΡ‚ Π΄Π°Π½Π½ΠΈ. ΠŸΡ€ΠΈ Ρ€Π΅Π°Π»Π½ΠΈ запитвания ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°Ρ…ΠΌΠ΅ ΡƒΠ²Π΅Π»ΠΈΡ‡Π°Π²Π°Π½Π΅ Π΄ΠΎ няколко стотин ΠΏΡŠΡ‚ΠΈ.

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

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

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

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