ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½Π° Π°Π½Π°Π»ΠΈΡ‚ΠΈΠΊΠ° Π²ΠΎ микросСрвис Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°: помош ΠΈ ΠΏΠΎΡ‚Ρ‚ΠΈΠΊΠ½ΡƒΠ²Π°ΡšΠ΅ Π½Π° Postgres FDW

ΠœΠΈΠΊΡ€ΠΎΡΠ΅Ρ€Π²ΠΈΡΠ½Π°Ρ‚Π° Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°, ΠΊΠ°ΠΊΠΎ ΠΈ сè Π½Π° овој свСт, ΠΈΠΌΠ° свои Π΄ΠΎΠ±Ρ€ΠΈΡ‚Π΅ ΠΈ Π»ΠΎΡˆΠΈΡ‚Π΅ страни. НСкои процСси стануваат полСсни со Π½Π΅Π³ΠΎ, Π΄Ρ€ΡƒΠ³ΠΈ ΠΏΠΎΡ‚Π΅ΡˆΠΊΠΈ. А Π·Π°Ρ€Π°Π΄ΠΈ Π±Ρ€Π·ΠΈΠ½Π°Ρ‚Π° Π½Π° ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈΡ‚Π΅ ΠΈ ΠΏΠΎΠ΄ΠΎΠ±Ρ€Π°Ρ‚Π° приспособливост, Ρ‚Ρ€Π΅Π±Π° Π΄Π° сС ΠΆΡ€Ρ‚Π²ΡƒΠ²Π°Ρ‚Π΅. Π•Π΄Π΅Π½ ΠΎΠ΄ Π½ΠΈΠ² Π΅ Π·Π³ΠΎΠ»Π΅ΠΌΠ΅Π½Π°Ρ‚Π° слоТСност Π½Π° Π°Π½Π°Π»ΠΈΡ‚ΠΈΠΊΠ°Ρ‚Π°. Ако Π²ΠΎ ΠΌΠΎΠ½ΠΎΠ»ΠΈΡ‚ Ρ†Π΅Π»Π°Ρ‚Π° ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½Π° Π°Π½Π°Π»ΠΈΡ‚ΠΈΠΊΠ° ΠΌΠΎΠΆΠ΅ Π΄Π° сС свСдС Π½Π° SQL Π±Π°Ρ€Π°ΡšΠ° Π΄ΠΎ Π°Π½Π°Π»ΠΈΡ‚ΠΈΡ‡ΠΊΠ° Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°, Ρ‚ΠΎΠ³Π°Ρˆ Π²ΠΎ мултисСрвисната Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π° сСкоја услуга ΠΈΠΌΠ° своја Π±Π°Π·Π° Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ ΠΈ сС Ρ‡ΠΈΠ½ΠΈ Π΄Π΅ΠΊΠ° Π΅Π΄Π½ΠΎ Π±Π°Ρ€Π°ΡšΠ΅ Π½Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π½Π°ΠΏΡ€Π°Π²ΠΈ (ΠΈΠ»ΠΈ ΠΌΠΎΠΆΠ΅Π±ΠΈ ΠΌΠΎΠΆΠ΅?). Π—Π° ΠΎΠ½ΠΈΠ΅ ΠΊΠΎΠΈ сС заинтСрСсирани ΠΊΠ°ΠΊΠΎ Π³ΠΎ Ρ€Π΅ΡˆΠΈΠ²ΠΌΠ΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΎΡ‚ со ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½Π°Ρ‚Π° Π°Π½Π°Π»ΠΈΡ‚ΠΈΠΊΠ° Π²ΠΎ Π½Π°ΡˆΠ°Ρ‚Π° компанија ΠΈ ΠΊΠ°ΠΊΠΎ Π½Π°ΡƒΡ‡ΠΈΠ²ΠΌΠ΅ Π΄Π° ΠΆΠΈΠ²Π΅Π΅ΠΌΠ΅ со ΠΎΠ²Π° Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ - Π΄ΠΎΠ±Ρ€Π΅Π΄ΠΎΡ˜Π΄Π΅.

ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½Π° Π°Π½Π°Π»ΠΈΡ‚ΠΈΠΊΠ° Π²ΠΎ микросСрвис Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°: помош ΠΈ ΠΏΠΎΡ‚Ρ‚ΠΈΠΊΠ½ΡƒΠ²Π°ΡšΠ΅ Π½Π° Postgres FDW
Јас сС Π²ΠΈΠΊΠ°ΠΌ ПавСл Биваш, Π²ΠΎ DomClick Ρ€Π°Π±ΠΎΡ‚Π°ΠΌ Π²ΠΎ Ρ‚ΠΈΠΌ кој Π΅ ΠΎΠ΄Π³ΠΎΠ²ΠΎΡ€Π΅Π½ Π·Π° ΠΎΠ΄Ρ€ΠΆΡƒΠ²Π°ΡšΠ΅ Π½Π° ΡΠΊΠ»Π°Π΄ΠΈΡˆΡ‚Π΅Ρ‚ΠΎ Π·Π° Π°Π½Π°Π»ΠΈΡ‚ΠΈΡ‡ΠΊΠΈ ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ. ΠšΠΎΠ½Π²Π΅Π½Ρ†ΠΈΠΎΠ½Π°Π»Π½ΠΎ, Π½Π°ΡˆΠΈΡ‚Π΅ активности ΠΌΠΎΠΆΠ΅ Π΄Π° сС класифицираат ΠΊΠ°ΠΊΠΎ инТСнСрство Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ, Π½ΠΎ, Π²ΡΡƒΡˆΠ½ΠΎΡΡ‚, опсСгот Π½Π° Π·Π°Π΄Π°Ρ‡ΠΈ Π΅ ΠΌΠ½ΠΎΠ³Ρƒ ΠΏΠΎΡˆΠΈΡ€ΠΎΠΊ. ΠŸΠΎΡΡ‚ΠΎΡ˜Π°Ρ‚ ETL/ELT стандард Π·Π° инТСнСрство Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ, ΠΏΠΎΠ΄Π΄Ρ€ΡˆΠΊΠ° ΠΈ Π°Π΄Π°ΠΏΡ‚Π°Ρ†ΠΈΡ˜Π° Π½Π° Π°Π»Π°Ρ‚ΠΊΠΈ Π·Π° Π°Π½Π°Π»ΠΈΠ·Π° Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ ΠΈ Ρ€Π°Π·Π²ΠΎΡ˜ Π½Π° сопствСни Π°Π»Π°Ρ‚ΠΊΠΈ. ΠšΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎ, Π·Π° ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½ΠΎΡ‚ΠΎ ΠΈΠ·Π²Π΅ΡΡ‚ΡƒΠ²Π°ΡšΠ΅, Ρ€Π΅ΡˆΠΈΠ²ΠΌΠ΅ Π΄Π° сС β€žΠΏΡ€Π΅ΠΏΡ€Π°Π²Π°ΠΌΠ΅β€œ Π΄Π΅ΠΊΠ° ΠΈΠΌΠ°ΠΌΠ΅ ΠΌΠΎΠ½ΠΎΠ»ΠΈΡ‚ ΠΈ Π΄Π° ΠΈΠΌ Π΄Π°Π΄Π΅ΠΌΠ΅ Π½Π° Π°Π½Π°Π»ΠΈΡ‚ΠΈΡ‡Π°Ρ€ΠΈΡ‚Π΅ Π΅Π΄Π½Π° Π±Π°Π·Π° Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ ΡˆΡ‚ΠΎ ќС Π³ΠΈ содрТи ситС ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ ΡˆΡ‚ΠΎ ΠΈΠΌ сС ΠΏΠΎΡ‚Ρ€Π΅Π±Π½ΠΈ.

Π’ΠΎ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ, Ρ€Π°Π·Π³Π»Π΅Π΄Π°Π²ΠΌΠ΅ Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ ΠΎΠΏΡ†ΠΈΠΈ. Π‘Π΅ΡˆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π΄Π° сС ΠΈΠ·Π³Ρ€Π°Π΄ΠΈ ΠΏΠΎΠ»Π½ΠΎΠΏΡ€Π°Π²Π½ΠΎ ΡΠΊΠ»Π°Π΄ΠΈΡˆΡ‚Π΅ - Π΄ΡƒΡ€ΠΈ ΠΈ сС ΠΎΠ±ΠΈΠ΄ΠΎΠ²ΠΌΠ΅, Π½ΠΎ, Π΄Π° Π±ΠΈΠ΄Π°ΠΌ искрСн, Π½Π΅ успСавмС Π΄Π° ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡ€Π°ΠΌΠ΅ ΠΏΡ€ΠΈΠ»ΠΈΡ‡Π½ΠΎ чСсти ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ Π²ΠΎ Π»ΠΎΠ³ΠΈΠΊΠ°Ρ‚Π° со ΠΏΡ€ΠΈΠ»ΠΈΡ‡Π½ΠΎ Π±Π°Π²Π½ΠΈΠΎΡ‚ процСс Π½Π° Π³Ρ€Π°Π΄Π΅ΡšΠ΅ ΡΠΊΠ»Π°Π΄ΠΈΡˆΡ‚Π΅ ΠΈ ΠΏΡ€Π°Π²Π΅ΡšΠ΅ ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ Π²ΠΎ Π½Π΅Π³ΠΎ (Π°ΠΊΠΎ нСкој успСС , ΠΏΠΈΡˆΠ΅Ρ‚Π΅ Π²ΠΎ ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€ ΠΊΠ°ΠΊΠΎ). На Π°Π½Π°Π»ΠΈΡ‚ΠΈΡ‡Π°Ρ€ΠΈΡ‚Π΅ моТСшС Π΄Π° ΠΈΠΌ сС ΠΊΠ°ΠΆΠ΅: β€žΠœΠΎΠΌΡ†ΠΈ, Π½Π°ΡƒΡ‡Π΅Ρ‚Π΅ ΠΏΠΈΡ‚ΠΎΠ½ ΠΈ ΠΎΠ΄Π΅Ρ‚Π΅ Π½Π° Π°Π½Π°Π»ΠΈΡ‚ΠΈΡ‡ΠΊΠΈ Ρ€Π΅ΠΏΠ»ΠΈΠΊΠΈβ€œ, Π½ΠΎ ΠΎΠ²Π° Π΅ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»Π΅Π½ услов Π·Π° Ρ€Π΅Π³Ρ€ΡƒΡ‚ΠΈΡ€Π°ΡšΠ΅ ΠΈ сС Ρ‡ΠΈΠ½Π΅ΡˆΠ΅ Π΄Π΅ΠΊΠ° ΠΎΠ²Π° Ρ‚Ρ€Π΅Π±Π° Π΄Π° сС ΠΈΠ·Π±Π΅Π³Π½Π΅ Π°ΠΊΠΎ Π΅ ΠΌΠΎΠΆΠ½ΠΎ. РСшивмС Π΄Π° сС ΠΎΠ±ΠΈΠ΄Π΅ΠΌΠ΅ Π΄Π° ја користимС Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΡ˜Π°Ρ‚Π° FDW (Foreign Data Wrapper): Π²ΠΎ ΡΡƒΡˆΡ‚ΠΈΠ½Π°, ΠΎΠ²Π° Π΅ стандардСн dblink, кој Π΅ Π²ΠΎ стандардот SQL, Π½ΠΎ со свој ΠΌΠ½ΠΎΠ³Ρƒ ΠΏΠΎΡƒΠ΄ΠΎΠ±Π΅Π½ ΠΈΠ½Ρ‚Π΅Ρ€Ρ„Π΅Ρ˜Ρ. Π’Ρ€Π· основа Π½Π° Ρ‚ΠΎΠ°, Π½Π°ΠΏΡ€Π°Π²ΠΈΠ²ΠΌΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΠ΅ Π½Π° ΠΊΡ€Π°Ρ˜ΠΎΡ‚ Ρ„Π°Ρ‚ΠΈ ΠΈ сС Ρ€Π΅ΡˆΠΈΠ²ΠΌΠ΅ Π½Π° Π½Π΅Π³ΠΎ. ΠΠ΅Ρ˜Π·ΠΈΠ½ΠΈΡ‚Π΅ Π΄Π΅Ρ‚Π°Π»ΠΈ сС Ρ‚Π΅ΠΌΠ° Π½Π° посСбна ΡΡ‚Π°Ρ‚ΠΈΡ˜Π°, Π° ΠΌΠΎΠΆΠ΅Π±ΠΈ ΠΈ повСќС ΠΎΠ΄ Π΅Π΄Π½Π°, бидСјќи сакам Π΄Π° Π·Π±ΠΎΡ€ΡƒΠ²Π°ΠΌ Π·Π° ΠΌΠ½ΠΎΠ³Ρƒ: ΠΎΠ΄ ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·ΠΈΡ€Π°ΡšΠ΅ шСми Π½Π° Π±Π°Π·ΠΈ Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ Π΄ΠΎ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π° Π½Π° пристап ΠΈ ΠΎΠ±Π΅Π·Π»ΠΈΡ‡ΡƒΠ²Π°ΡšΠ΅ Π½Π° Π»ΠΈΡ‡Π½ΠΈΡ‚Π΅ ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ. Π˜ΡΡ‚ΠΎ Ρ‚Π°ΠΊΠ°, Π½Π΅ΠΎΠΏΡ…ΠΎΠ΄Π½ΠΎ Π΅ Π΄Π° сС Π½Π°ΠΏΡ€Π°Π²ΠΈ Ρ€Π΅Π·Π΅Ρ€Π²Π°Ρ†ΠΈΡ˜Π° Π΄Π΅ΠΊΠ° ΠΎΠ²Π° Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π½Π΅ Π΅ Π·Π°ΠΌΠ΅Π½Π° Π·Π° вистински Π°Π½Π°Π»ΠΈΡ‚ΠΈΡ‡ΠΊΠΈ Π±Π°Π·ΠΈ Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ ΠΈ ΡΠΊΠ»Π°Π΄ΠΈΡˆΡ‚Π°, Ρ‚ΡƒΠΊΡƒ Ρ€Π΅ΡˆΠ°Π²Π° само ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π΅Π½ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ.

На највисоко ниво изглСда вака:

ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½Π° Π°Π½Π°Π»ΠΈΡ‚ΠΈΠΊΠ° Π²ΠΎ микросСрвис Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°: помош ΠΈ ΠΏΠΎΡ‚Ρ‚ΠΈΠΊΠ½ΡƒΠ²Π°ΡšΠ΅ Π½Π° Postgres FDW
ΠŸΠΎΡΡ‚ΠΎΠΈ Π±Π°Π·Π° Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ PostgreSQL ΠΊΠ°Π΄Π΅ ΡˆΡ‚ΠΎ корисницитС ΠΌΠΎΠΆΠ°Ρ‚ Π΄Π° Π³ΠΈ складираат своитС Ρ€Π°Π±ΠΎΡ‚Π½ΠΈ ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ, Π° најваТно Π΅ ΡˆΡ‚ΠΎ Π°Π½Π°Π»ΠΈΡ‚ΠΈΡ‡ΠΊΠΈΡ‚Π΅ Ρ€Π΅ΠΏΠ»ΠΈΠΊΠΈ Π½Π° ситС услуги сС ΠΏΠΎΠ²Ρ€Π·Π°Π½ΠΈ со ΠΎΠ²Π°Π° Π±Π°Π·Π° ΠΏΡ€Π΅ΠΊΡƒ FDW. Ова ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡƒΠ²Π° Π΄Π° сС напишС Π±Π°Ρ€Π°ΡšΠ΅ Π²ΠΎ Π½Π΅ΠΊΠΎΠ»ΠΊΡƒ Π±Π°Π·ΠΈ Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ ΠΈ Π½Π΅ Π΅ Π²Π°ΠΆΠ½ΠΎ ΡˆΡ‚ΠΎ Π΅ Ρ‚ΠΎΠ°: PostgreSQL, MySQL, MongoDB ΠΈΠ»ΠΈ Π½Π΅ΡˆΡ‚ΠΎ Π΄Ρ€ΡƒΠ³ΠΎ (Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ°, API, Π°ΠΊΠΎ одСднаш Π½Π΅ΠΌΠ° соодвСтна ΠΎΠ±Π²ΠΈΠ²ΠΊΠ°, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π½Π°ΠΏΠΈΡˆΠ΅Ρ‚Π΅ своја). Па, сè ΠΈΠ·Π³Π»Π΅Π΄Π° ΠΎΠ΄Π»ΠΈΡ‡Π½ΠΎ! Π”Π°Π»ΠΈ раскинувамС?

Ако сè Π·Π°Π²Ρ€ΡˆΠΈ Ρ‚ΠΎΠ»ΠΊΡƒ Π±Ρ€Π·ΠΎ ΠΈ Сдноставно, Ρ‚ΠΎΠ³Π°Ρˆ, Π²Π΅Ρ€ΠΎΡ˜Π°Ρ‚Π½ΠΎ, Π½Π΅ΠΌΠ° Π΄Π° ΠΈΠΌΠ° ΡΡ‚Π°Ρ‚ΠΈΡ˜Π°.

Π’Π°ΠΆΠ½ΠΎ Π΅ Π΄Π° сС Π±ΠΈΠ΄Π΅ јасно ΠΊΠ°ΠΊΠΎ Postgres Π³ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΡƒΠ²Π° Π±Π°Ρ€Π°ΡšΠ°Ρ‚Π° Π΄ΠΎ ΠΎΠ΄Π΄Π°Π»Π΅Ρ‡Π΅Π½ΠΈΡ‚Π΅ сСрвСри. Ова ΠΈΠ·Π³Π»Π΅Π΄Π° Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ, Π½ΠΎ чСсто Π»ΡƒΡ“Π΅Ρ‚ΠΎ Π½Π΅ ΠΎΠ±Ρ€Π½ΡƒΠ²Π°Π°Ρ‚ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° Ρ‚ΠΎΠ°: Postgres Π³ΠΎ Π΄Π΅Π»ΠΈ Π±Π°Ρ€Π°ΡšΠ΅Ρ‚ΠΎ Π½Π° Π΄Π΅Π»ΠΎΠ²ΠΈ ΠΊΠΎΠΈ сС ΠΈΠ·Π²Ρ€ΡˆΡƒΠ²Π°Π°Ρ‚ нСзависно Π½Π° ΠΎΠ΄Π΄Π°Π»Π΅Ρ‡Π΅Π½ΠΈΡ‚Π΅ сСрвСри, Π³ΠΈ собира ΠΎΠ²ΠΈΠ΅ ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ ΠΈ самиот Π³ΠΈ ΠΈΠ·Π²Ρ€ΡˆΡƒΠ²Π° ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΈΡ‚Π΅ прСсмСтки, Ρ‚Π°ΠΊΠ° ΡˆΡ‚ΠΎ Π±Ρ€Π·ΠΈΠ½Π°Ρ‚Π° Π½Π° ΠΈΠ·Π²Ρ€ΡˆΡƒΠ²Π°ΡšΠ΅ Π½Π° Π±Π°Ρ€Π°ΡšΠ΅Ρ‚ΠΎ Π²ΠΎ Π³ΠΎΠ»Π΅ΠΌΠ° ΠΌΠ΅Ρ€Π° ќС зависи ΠΎΠ΄ ΠΊΠ°ΠΊΠΎ Π΅ напишано. Π˜ΡΡ‚ΠΎ Ρ‚Π°ΠΊΠ°, Ρ‚Ρ€Π΅Π±Π° Π΄Π° сС Π·Π°Π±Π΅Π»Π΅ΠΆΠΈ: ΠΊΠΎΠ³Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈΡ‚Π΅ пристигнуваат ΠΎΠ΄ ΠΎΠ΄Π΄Π°Π»Π΅Ρ‡Π΅Π½ сСрвСр, Ρ‚ΠΈΠ΅ вСќС Π½Π΅ΠΌΠ°Π°Ρ‚ индСкси, Π½Π΅ΠΌΠ° Π½ΠΈΡˆΡ‚ΠΎ ΡˆΡ‚ΠΎ ќС ΠΌΡƒ ΠΏΠΎΠΌΠΎΠ³Π½Π΅ Π½Π° распорСдувачот, Π·Π°Ρ‚ΠΎΠ°, само Π½ΠΈΠ΅ самитС ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° ΠΌΡƒ ΠΏΠΎΠΌΠΎΠ³Π½Π΅ΠΌΠ΅ ΠΈ Π΄Π° Π³ΠΎ совСтувамС. И Ρ‚ΠΎΠΊΠΌΡƒ Π·Π° ΠΎΠ²Π° сакам Π΄Π° Π·Π±ΠΎΡ€ΡƒΠ²Π°ΠΌ ΠΏΠΎΠ΄Π΅Ρ‚Π°Π»Π½ΠΎ.

Едноставно Π±Π°Ρ€Π°ΡšΠ΅ ΠΈ ΠΏΠ»Π°Π½ со Π½Π΅Π³ΠΎ

Π—Π° Π΄Π° ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ 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 ΠΏΠΎΠ»Π΅, Π΅Π΄Π΅Π½ ΠΏΠΎ појава врСмСнската ΠΎΠ·Π½Π°ΠΊΠ° Π²ΠΎ ΠΈΠ½Ρ‚Π΅Ρ€Π²Π°Π»ΠΎΡ‚ ΠΈ Π΅Π΄Π΅Π½ ΠΎΠ΄ 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 ΠΌΠΈΠ»ΠΈΠΎΠ½ΠΈ Ρ€Π΅Π΄ΠΎΠ²ΠΈ Π·Π° ΠΏΠΎΡ‚ΠΎΠ° Π΄Π° сС Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ€Π° Π»ΠΎΠΊΠ°Π»Π½ΠΎ (Π Π΅Π΄ΠΎΡ‚ Π½Π° Ρ„ΠΈΠ»Ρ‚Π΅Ρ€) ΠΈ Π΄Π° ΠΈΠ·Π²Ρ€ΡˆΠΈ Π°Π³Ρ€Π΅Π³Π°Ρ†ΠΈΡ˜Π°. ΠšΠ»ΡƒΡ‡ΠΎΡ‚ Π·Π° успСхот Π΅ Π΄Π° сС напишС Π±Π°Ρ€Π°ΡšΠ΅, Ρ‚Π°ΠΊΠ° ΡˆΡ‚ΠΎ Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ‚Π΅ сС ΠΏΡ€Π΅Ρ„Ρ€Π»Π°Π°Ρ‚ Π½Π° ΠΎΠ΄Π΄Π°Π»Π΅Ρ‡Π΅Π½Π°Ρ‚Π° машина, Π° Π½ΠΈΠ΅ Π³ΠΈ ΠΏΡ€ΠΈΠΌΠ°ΠΌΠ΅ ΠΈ собирамС само ΠΏΠΎΡ‚Ρ€Π΅Π±Π½ΠΈΡ‚Π΅ Ρ€Π΅Π΄ΠΎΠ²ΠΈ.

Π’ΠΎΠ° Π΅ нСкоја глупост

Π‘ΠΎ Π±ΡƒΠ»ΠΎΠ²Π° полиња сè Π΅ Сдноставно. Π’ΠΎ ΠΏΡ€Π²ΠΎΠ±ΠΈΡ‚Π½ΠΎΡ‚ΠΎ Π±Π°Ρ€Π°ΡšΠ΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΎΡ‚ сС Π΄ΠΎΠ»ΠΆΠΈ Π½Π° ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΡ‚ is. Ако Π³ΠΎ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚Π΅ со =, Ρ‚ΠΎΠ³Π°Ρˆ Π³ΠΎ Π΄ΠΎΠ±ΠΈΠ²Π°ΠΌΠ΅ слСдниот Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚:

explain analyze verbose
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';

Aggregate  (cost=508010.14..508010.15 rows=1 width=8) (actual time=19064.314..19064.314 rows=1 loops=1)
  Output: count(1)
  ->  Foreign Scan on fdw_schema."table"  (cost=100.00..507988.44 rows=8679 width=0) (actual time=33.035..18951.278 rows=1360025 loops=1)
        Output: "table".id, "table".is_active, "table".meta, "table".created_dt
        Filter: ((("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: 3567989
        Remote SQL: SELECT created_dt, meta FROM fdw_schema.table WHERE (is_active)
Planning time: 0.834 ms
Execution time: 19064.534 ms

Како ΡˆΡ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π²ΠΈΠ΄ΠΈΡ‚Π΅, Ρ„ΠΈΠ»Ρ‚Π΅Ρ€ΠΎΡ‚ ΠΏΠΎΠ»Π΅Ρ‚Π° Π΄ΠΎ ΠΎΠ΄Π΄Π°Π»Π΅Ρ‡Π΅Π½ сСрвСр, Π° Π²Ρ€Π΅ΠΌΠ΅Ρ‚ΠΎ Π½Π° ΠΈΠ·Π²Ρ€ΡˆΡƒΠ²Π°ΡšΠ΅ бСшС Π½Π°ΠΌΠ°Π»Π΅Π½ΠΎ ΠΎΠ΄ 27 Π½Π° 19 сСкунди.

Π’Ρ€Π΅Π΄ΠΈ Π΄Π° сС Π½Π°ΠΏΠΎΠΌΠ΅Π½Π΅ Π΄Π΅ΠΊΠ° ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΡ‚ is Ρ€Π°Π·Π»ΠΈΡ‡Π΅Π½ ΠΎΠ΄ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΡ‚ = бидСјќи ΠΌΠΎΠΆΠ΅ Π΄Π° Ρ€Π°Π±ΠΎΡ‚ΠΈ со Null врСдноста. Π’ΠΎΠ° Π·Π½Π°Ρ‡ΠΈ Π΄Π΅ΠΊΠ° Π½Π΅ Π΅ Вистина ќС Π³ΠΈ остави врСдноститС False ΠΈ Null Π²ΠΎ Ρ„ΠΈΠ»Ρ‚Π΅Ρ€ΠΎΡ‚, Π΄ΠΎΠ΄Π΅ΠΊΠ° != Π’ΠΎΡ‡Π½ΠΎ ќС остави само Π›Π°ΠΆΠ½ΠΈ врСдности. Π—Π°Ρ‚ΠΎΠ°, ΠΏΡ€ΠΈ Π·Π°ΠΌΠ΅Π½Π° Π½Π° ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΡ‚ Π½Π΅ Π΄Π²Π° услови со ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΡ‚ Π˜Π›Π˜ Ρ‚Ρ€Π΅Π±Π° Π΄Π° сС прСнСсат Π½Π° Ρ„ΠΈΠ»Ρ‚Π΅Ρ€ΠΎΡ‚, Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€, WHERE (ΠΊΠΎΠ» != Π’ΠΎΡ‡Π½ΠΎ) Π˜Π›Π˜ (ΠΊΠΎΠ»ΠΊΠ°Ρ‚Π° Π΅ Π½ΡƒΠ»Π°).

Π‘Π΅ Π·Π°Π½ΠΈΠΌΠ°Π²Π°Π²ΠΌΠ΅ со Π±ΡƒΠ», ајдС Π΄Π° ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΠΌΠ΅ ΠΏΠΎΠ½Π°Ρ‚Π°ΠΌΡƒ. ЗасСга, Π΄Π° Π³ΠΎ Π²Ρ€Π°Ρ‚ΠΈΠΌΠ΅ Π‘ΡƒΠ»ΠΎΠ²ΠΈΠΎΡ‚ Ρ„ΠΈΠ»Ρ‚Π΅Ρ€ Π²ΠΎ Π½Π΅Π³ΠΎΠ²Π°Ρ‚Π° ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»Π½Π° Ρ„ΠΎΡ€ΠΌΠ° со Ρ†Π΅Π» ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡ˜Π½ΠΎ Π΄Π° Π³ΠΎ Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ Π΅Ρ„Π΅ΠΊΡ‚ΠΎΡ‚ ΠΎΠ΄ Π΄Ρ€ΡƒΠ³ΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ.

timestamptz? hz

Π’ΠΎ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ, чСстопати Ρ‚Ρ€Π΅Π±Π° Π΄Π° СкспСримСнтиратС ΠΊΠ°ΠΊΠΎ ΠΏΡ€Π°Π²ΠΈΠ»Π½ΠΎ Π΄Π° Π½Π°ΠΏΠΈΡˆΠ΅Ρ‚Π΅ Π±Π°Ρ€Π°ΡšΠ΅ ΡˆΡ‚ΠΎ Π²ΠΊΠ»ΡƒΡ‡ΡƒΠ²Π° ΠΎΠ΄Π΄Π°Π»Π΅Ρ‡Π΅Π½ΠΈ сСрвСри ΠΈ Π΄ΡƒΡ€ΠΈ ΠΏΠΎΡ‚ΠΎΠ° Π΄Π° Π±Π°Ρ€Π°Ρ‚Π΅ ΠΎΠ±Ρ˜Π°ΡΠ½ΡƒΠ²Π°ΡšΠ΅ Π·ΠΎΡˆΡ‚ΠΎ Ρ‚ΠΎΠ° сС случува. ΠœΠ½ΠΎΠ³Ρƒ ΠΌΠ°Π»ΠΊΡƒ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ Π·Π° ΠΎΠ²Π° ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π½Π°Ρ˜Π΄Π°Ρ‚ Π½Π° Π˜Π½Ρ‚Π΅Ρ€Π½Π΅Ρ‚. Π’Π°ΠΊΠ°, Π²ΠΎ СкспСримСнтитС ΠΎΡ‚ΠΊΡ€ΠΈΠ²ΠΌΠ΅ Π΄Π΅ΠΊΠ° Ρ„ΠΈΠ»Ρ‚Π΅Ρ€ΠΎΡ‚ Π·Π° фиксСн Π΄Π°Ρ‚ΡƒΠΌ Π»Π΅Ρ‚Π° Π΄ΠΎ ΠΎΠ΄Π΄Π°Π»Π΅Ρ‡Π΅Π½ΠΈΠΎΡ‚ сСрвСр со трСсок, Π½ΠΎ ΠΊΠΎΠ³Π° сакамС Π΄ΠΈΠ½Π°ΠΌΠΈΡ‡ΠΊΠΈ Π΄Π° Π³ΠΎ поставимС Π΄Π°Ρ‚ΡƒΠΌΠΎΡ‚, Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€, now() ΠΈΠ»ΠΈ CURRENT_DATE, Ρ‚ΠΎΠ° Π½Π΅ сС случува. Π’ΠΎ Π½Π°ΡˆΠΈΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π΄ΠΎΠ΄Π°Π΄ΠΎΠ²ΠΌΠ΅ Ρ„ΠΈΠ»Ρ‚Π΅Ρ€ Ρ‚Π°ΠΊΠ° ΡˆΡ‚ΠΎ ΠΊΠΎΠ»ΠΎΠ½Π°Ρ‚Π° create_at содрТи ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ Π·Π° Ρ‚ΠΎΡ‡Π½ΠΎ 1 мСсСц Π²ΠΎ ΠΌΠΈΠ½Π°Ρ‚ΠΎΡ‚ΠΎ (BETWEEN CURRENT_DATE - INTERVAL β€ž7 ΠΌΠ΅ΡΠ΅Ρ†β€œ И CURRENT_DATE - INTERVAL β€ž6 ΠΌΠ΅ΡΠ΅Ρ†β€œ). Π¨Ρ‚ΠΎ Π½Π°ΠΏΡ€Π°Π²ΠΈΠ²ΠΌΠ΅ Π²ΠΎ овој ΡΠ»ΡƒΡ‡Π°Ρ˜?

explain analyze verbose
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 <(SELECT CURRENT_DATE::timestamptz - INTERVAL '6 month')
AND meta->>'source' = 'test';

Aggregate  (cost=306875.17..306875.18 rows=1 width=8) (actual time=4789.114..4789.115 rows=1 loops=1)
  Output: count(1)
  InitPlan 1 (returns $0)
    ->  Result  (cost=0.00..0.02 rows=1 width=8) (actual time=0.007..0.008 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.002..0.002 rows=1 loops=1)
          Output: ((('now'::cstring)::date)::timestamp with time zone - '6 mons'::interval)
  ->  Foreign Scan on fdw_schema."table"  (cost=100.02..306874.86 rows=105 width=0) (actual time=23.475..4681.419 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))
        Rows Removed by Filter: 76934
        Remote 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))
Planning time: 0.703 ms
Execution time: 4789.379 ms

ΠœΡƒ ΠΊΠ°ΠΆΠ°Π²ΠΌΠ΅ Π½Π° ΠΏΠ»Π°Π½Π΅Ρ€ΠΎΡ‚ ΠΎΠ΄Π½Π°ΠΏΡ€Π΅Π΄ Π΄Π° Π³ΠΎ прСсмСта Π΄Π°Ρ‚ΡƒΠΌΠΎΡ‚ Π²ΠΎ ΠΏΠΎΠ΄ΠΏΡ€Π°ΡˆΠ°ΡšΠ΅Ρ‚ΠΎ ΠΈ Π΄Π° ја прСнСсС Π³ΠΎΡ‚ΠΎΠ²Π°Ρ‚Π° ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π° Π½Π° Ρ„ΠΈΠ»Ρ‚Π΅Ρ€ΠΎΡ‚. И овој Π½Π°Π²Π΅ΡΡ‚ΡƒΠ²Π°ΡšΠ΅ Π½ΠΈ Π΄Π°Π΄Π΅ ΠΎΠ΄Π»ΠΈΡ‡Π΅Π½ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚, Π±Π°Ρ€Π°ΡšΠ΅Ρ‚ΠΎ стана скоро 6 ΠΏΠ°Ρ‚ΠΈ ΠΏΠΎΠ±Ρ€Π·ΠΎ!

ΠŸΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ, Π²Π°ΠΆΠ½ΠΎ Π΅ Π΄Π° сС Π±ΠΈΠ΄Π΅ Π²Π½ΠΈΠΌΠ°Ρ‚Π΅Π»Π΅Π½ ΠΎΠ²Π΄Π΅: Ρ‚ΠΈΠΏΠΎΡ‚ Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ Π²ΠΎ ΠΏΠΎΠ΄ΠΏΡ€Π°ΡˆΠ°ΡšΠ΅Ρ‚ΠΎ ΠΌΠΎΡ€Π° Π΄Π° Π±ΠΈΠ΄Π΅ ист ΠΊΠ°ΠΊΠΎ оној Π½Π° ΠΏΠΎΠ»Π΅Ρ‚ΠΎ Π½Π° ΠΊΠΎΠ΅ Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ€Π°ΠΌΠ΅, ΠΈΠ½Π°ΠΊΡƒ ΠΏΠ»Π°Π½Π΅Ρ€ΠΎΡ‚ ќС ΠΎΠ΄Π»ΡƒΡ‡ΠΈ Π΄Π΅ΠΊΠ° бидСјќи Ρ‚ΠΈΠΏΠΎΠ²ΠΈΡ‚Π΅ сС Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ, ΠΏΠΎΡ‚Ρ€Π΅Π±Π½ΠΎ Π΅ ΠΏΡ€Π²ΠΎ Π΄Π° сС Π΄ΠΎΠ±ΠΈΡ˜Π°Ρ‚ ситС ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈΡ‚Π΅ ΠΈ Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ€Π°Ρ˜Ρ‚Π΅ Π³ΠΈ Π»ΠΎΠΊΠ°Π»Π½ΠΎ.

Π”Π° Π³ΠΎ Π²Ρ€Π°Ρ‚ΠΈΠΌΠ΅ Ρ„ΠΈΠ»Ρ‚Π΅Ρ€ΠΎΡ‚ Π·Π° Π΄Π°Ρ‚ΡƒΠΌ Π½Π° Π½Π΅Π³ΠΎΠ²Π°Ρ‚Π° ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»Π½Π° врСдност.

Π€Ρ€Π΅Π΄ΠΈ vs. Јсонб

ΠžΠΏΡˆΡ‚ΠΎ Π·Π΅ΠΌΠ΅Π½ΠΎ, Π‘ΡƒΠ»ΠΎΠ²ΠΈΡ‚Π΅ полиња ΠΈ Π΄Π°Ρ‚ΡƒΠΌΠΈ вСќС Π΄ΠΎΠ²ΠΎΠ»Π½ΠΎ Π³ΠΎ Π·Π°Π±Ρ€Π·Π°Π° Π½Π°ΡˆΠ΅Ρ‚ΠΎ Π±Π°Ρ€Π°ΡšΠ΅, Π½ΠΎ остана ΡƒΡˆΡ‚Π΅ Π΅Π΄Π΅Π½ Ρ‚ΠΈΠΏ Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ. Π‘ΠΈΡ‚ΠΊΠ°Ρ‚Π° со Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ€Π°ΡšΠ΅Ρ‚ΠΎ ΠΏΠΎ Π½Π΅Π³ΠΎ, Π΄Π° Π±ΠΈΠ΄Π°ΠΌ искрСн, сè ΡƒΡˆΡ‚Π΅ Π½Π΅ Π΅ Π·Π°Π²Ρ€ΡˆΠ΅Π½Π°, ΠΈΠ°ΠΊΠΎ ΠΈ Ρ‚ΡƒΠΊΠ° ΠΈΠΌΠ° успСх. Π’Π°ΠΊΠ°, Π²Π°ΠΊΠ° успСавмС Π΄Π° Π³ΠΎ ΠΏΠΎΠΌΠΈΠ½Π΅ΠΌΠ΅ Ρ„ΠΈΠ»Ρ‚Π΅Ρ€ΠΎΡ‚ 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"}'::jsonb;

Aggregate  (cost=245463.60..245463.61 rows=1 width=8) (actual time=6727.589..6727.590 rows=1 loops=1)
  Output: count(1)
  ->  Foreign Scan on fdw_schema."table"  (cost=1100.00..245459.90 rows=1478 width=0) (actual time=16.213..6634.794 rows=1360025 loops=1)
        Output: "table".id, "table".is_active, "table".meta, "table".created_dt
        Filter: (("table".is_active IS TRUE) 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: 619961
        Remote SQL: SELECT created_dt, is_active FROM fdw_schema.table WHERE ((meta @> '{"source": "test"}'::jsonb))
Planning time: 0.747 ms
Execution time: 6727.815 ms

НамСсто Π΄Π° Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ€Π°Ρ‚Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΈ, ΠΌΠΎΡ€Π° Π΄Π° користитС присуство Π½Π° Π΅Π΄Π΅Π½ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ jsonb Π²ΠΎ Π΅Π΄Π½Π° ΠΏΠΎΠΈΠ½Π°ΠΊΠ²Π°. 7 сСкунди намСсто ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»Π½ΠΈΡ‚Π΅ 29. ЗасСга ΠΎΠ²Π° Π΅ СдинствСната ΡƒΡΠΏΠ΅ΡˆΠ½Π° ΠΎΠΏΡ†ΠΈΡ˜Π° Π·Π° прСнос Π½Π° Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ ΠΏΡ€Π΅ΠΊΡƒ jsonb Π½Π° ΠΎΠ΄Π΄Π°Π»Π΅Ρ‡Π΅Π½ сСрвСр, Π½ΠΎ Ρ‚ΡƒΠΊΠ° Π΅ Π²Π°ΠΆΠ½ΠΎ Π΄Π° сС Π·Π΅ΠΌΠ΅ ΠΏΡ€Π΅Π΄Π²ΠΈΠ΄ Π΅Π΄Π½ΠΎ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΡƒΠ²Π°ΡšΠ΅: ја користимС Π²Π΅Ρ€Π·ΠΈΡ˜Π°Ρ‚Π° 9.6 ΠΎΠ΄ Π±Π°Π·Π°Ρ‚Π° Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ, Π½ΠΎ Π΄ΠΎ ΠΊΡ€Π°Ρ˜ΠΎΡ‚ Π½Π° Π°ΠΏΡ€ΠΈΠ» ΠΏΠ»Π°Π½ΠΈΡ€Π°ΠΌΠ΅ Π΄Π° Π³ΠΈ Π·Π°Π²Ρ€ΡˆΠΈΠΌΠ΅ послСднитС тСстови ΠΈ Π΄Π° ΠΏΡ€Π΅ΠΌΠΈΠ½Π΅ΠΌΠ΅ Π½Π° Π²Π΅Ρ€Π·ΠΈΡ˜Π°Ρ‚Π° 12. ΠžΡ‚ΠΊΠ°ΠΊΠΎ ќС сС Π°ΠΆΡƒΡ€ΠΈΡ€Π°ΠΌΠ΅, ќС ΠΏΠΈΡˆΡƒΠ²Π°ΠΌΠ΅ Π·Π° Ρ‚ΠΎΠ° ΠΊΠ°ΠΊΠΎ Ρ‚ΠΎΠ° влијаСло, бидСјќи ΠΈΠΌΠ° доста ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ Π·Π° ΠΊΠΎΠΈ ΠΈΠΌΠ° ΠΌΠ½ΠΎΠ³Ρƒ Π½Π°Π΄Π΅ΠΆ: json_path, Π½ΠΎΠ²ΠΎ ΠΎΠ΄Π½Π΅ΡΡƒΠ²Π°ΡšΠ΅ Π½Π° CTE, притисни Π½Π°Π΄ΠΎΠ»Ρƒ (постои ΠΎΠ΄ Π²Π΅Ρ€Π·ΠΈΡ˜Π°Ρ‚Π° 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 <(SELECT CURRENT_DATE::timestamptz - INTERVAL '6 month')
AND meta @> '{"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 < $2::timestamp with time zone)) AND ((meta @> '{"source": "test"}'::jsonb))
Planning time: 0.820 ms
Execution time: 2279.087 ms

Π”Π°, Π±Π°Ρ€Π°ΡšΠ΅Ρ‚ΠΎ ΠΈΠ·Π³Π»Π΅Π΄Π° ΠΏΠΎΠΊΠΎΠΌΠΏΠ»ΠΈΡ†ΠΈΡ€Π°Π½ΠΎ, ΠΎΠ²Π° Π΅ ΠΏΡ€ΠΈΠ½ΡƒΠ΄Π½Π° такса, Π½ΠΎ Π±Ρ€Π·ΠΈΠ½Π°Ρ‚Π° Π½Π° ΠΈΠ·Π²Ρ€ΡˆΡƒΠ²Π°ΡšΠ΅ Π΅ 2 сСкунди, ΡˆΡ‚ΠΎ Π΅ повСќС ΠΎΠ΄ 10 ΠΏΠ°Ρ‚ΠΈ ΠΏΠΎΠ±Ρ€Π·ΠΎ! И Π½ΠΈΠ΅ Π·Π±ΠΎΡ€ΡƒΠ²Π°ΠΌΠ΅ Π·Π° Сдноставно Π±Π°Ρ€Π°ΡšΠ΅ ΠΏΡ€ΠΎΡ‚ΠΈΠ² Ρ€Π΅Π»Π°Ρ‚ΠΈΠ²Π½ΠΎ ΠΌΠ°Π» сСт Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ. На Ρ€Π΅Π°Π»Π½ΠΈ Π±Π°Ρ€Π°ΡšΠ° Π΄ΠΎΠ±ΠΈΠ²ΠΌΠ΅ Π·Π³ΠΎΠ»Π΅ΠΌΡƒΠ²Π°ΡšΠ΅ ΠΈ Π΄ΠΎ Π½Π΅ΠΊΠΎΠ»ΠΊΡƒ стотици ΠΏΠ°Ρ‚ΠΈ.

Π”Π° Ρ€Π΅Π·ΠΈΠΌΠΈΡ€Π°ΠΌΠ΅: Π°ΠΊΠΎ користитС PostgreSQL со FDW, сСкогаш ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡƒΠ²Π°Ρ˜Ρ‚Π΅ Π΄Π°Π»ΠΈ ситС Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ сС ΠΈΡΠΏΡ€Π°ΡœΠ°Π°Ρ‚ Π΄ΠΎ далСчинскиот сСрвСр ΠΈ ќС Π±ΠΈΠ΄Π΅Ρ‚Π΅ ΡΡ€Π΅ΡœΠ½ΠΈ... Π‘Π°Ρ€Π΅ΠΌ Π΄ΠΎΠ΄Π΅ΠΊΠ° Π½Π΅ стигнСтС Π΄Π° сС ΠΏΡ€ΠΈΠΊΠ»ΡƒΡ‡ΠΈΡ‚Π΅ ΠΏΠΎΠΌΠ΅Ρ“Ρƒ Ρ‚Π°Π±Π΅Π»ΠΈΡ‚Π΅ ΠΎΠ΄ Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ сСрвСри. Но, Ρ‚ΠΎΠ° Π΅ ΠΏΡ€ΠΈΠΊΠ°Π·Π½Π° Π·Π° Π΄Ρ€ΡƒΠ³Π° ΡΡ‚Π°Ρ‚ΠΈΡ˜Π°.

Π’ΠΈ Π±Π»Π°Π³ΠΎΠ΄Π°Ρ€ΠΈΠΌΠ΅ Π·Π° Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅Ρ‚ΠΎ! Π‘ΠΈ сакал Π΄Π° ΡΠ»ΡƒΡˆΠ½Π°ΠΌ ΠΏΡ€Π°ΡˆΠ°ΡšΠ°, ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈ ΠΈ ΠΏΡ€ΠΈΠΊΠ°Π·Π½ΠΈ Π·Π° Π²Π°ΡˆΠΈΡ‚Π΅ искуства Π²ΠΎ ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΡ‚Π΅.

Π˜Π·Π²ΠΎΡ€: www.habr.com

Π”ΠΎΠ΄Π°Π΄Π΅Ρ‚Π΅ ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€