ΠΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ°ΡΠ° Π½Π° ΠΌΠΈΠΊΡΠΎΡΠ΅ΡΠ²ΠΈΠ·ΠΈΡΠ΅, ΠΊΠ°ΠΊΡΠΎ Π²ΡΠΈΡΠΊΠΎ Π½Π° ΡΠΎΠ·ΠΈ ΡΠ²ΡΡ, ΠΈΠΌΠ° ΡΠ²ΠΎΠΈΡΠ΅ ΠΏΠ»ΡΡΠΎΠ²Π΅ ΠΈ ΠΌΠΈΠ½ΡΡΠΈ. ΠΡΠΊΠΎΠΈ ΠΏΡΠΎΡΠ΅ΡΠΈ ΡΡΠ°Π²Π°Ρ ΠΏΠΎ-Π»Π΅ΡΠ½ΠΈ Ρ Π½Π΅Π³ΠΎ, Π΄ΡΡΠ³ΠΈ ΠΏΠΎ-ΡΡΡΠ΄Π½ΠΈ. Π Π² ΠΈΠΌΠ΅ΡΠΎ Π½Π° ΡΠΊΠΎΡΠΎΡΡΡΠ° Π½Π° ΠΏΡΠΎΠΌΡΠ½Π°ΡΠ° ΠΈ ΠΏΠΎ-Π΄ΠΎΠ±ΡΠ°ΡΠ° ΠΌΠ°ΡΠ°Π±ΠΈΡΡΠ΅ΠΌΠΎΡΡ ΡΡΡΠ±Π²Π° Π΄Π° ΠΏΡΠ°Π²ΠΈΡΠ΅ ΠΆΠ΅ΡΡΠ²ΠΈ. ΠΠ΄Π½Π° ΠΎΡ ΡΡΡ Π΅ ΡΠ»ΠΎΠΆΠ½ΠΎΡΡΡΠ° Π½Π° Π°Π½Π°Π»ΠΈΠ·Π°. ΠΠΊΠΎ Π² ΠΌΠΎΠ½ΠΎΠ»ΠΈΡ Π²ΡΠΈΡΠΊΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠ²Π½ΠΈ Π°Π½Π°Π»ΠΈΠ·ΠΈ ΠΌΠΎΠ³Π°Ρ Π΄Π° Π±ΡΠ΄Π°Ρ Π½Π°ΠΌΠ°Π»Π΅Π½ΠΈ Π΄ΠΎ SQL Π·Π°ΡΠ²ΠΊΠΈ ΠΊΡΠΌ Π°Π½Π°Π»ΠΈΡΠΈΡΠ½Π° ΡΠ΅ΠΏΠ»ΠΈΠΊΠ°, ΡΠΎΠ³Π°Π²Π° Π² ΠΌΡΠ»ΡΠΈΡΠ΅ΡΠ²ΠΈΠ·Π½Π° Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ° Π²ΡΡΠΊΠ° ΡΡΠ»ΡΠ³Π° ΠΈΠΌΠ° ΡΠ²ΠΎΡ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π° Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ ΠΈ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π°, ΡΠ΅ Π΅Π΄Π½Π° Π·Π°ΡΠ²ΠΊΠ° Π½Π΅ Π΅ Π΄ΠΎΡΡΠ°ΡΡΡΠ½Π° (ΠΈΠ»ΠΈ ΠΌΠΎΠΆΠ΅ Π±ΠΈ ΡΠ΅ ΡΡΠ°Π½Π΅?). ΠΠ° ΡΠ΅Π·ΠΈ, ΠΊΠΎΠΈΡΠΎ ΡΠ΅ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΡΠ²Π°Ρ ΠΊΠ°ΠΊ ΡΠ΅ΡΠΈΡ ΠΌΠ΅ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ° Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠ²Π½ΠΈΡ Π°Π½Π°Π»ΠΈΠ· Π² Π½Π°ΡΠ°ΡΠ° ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΡ ΠΈ ΠΊΠ°ΠΊ ΡΠ΅ Π½Π°ΡΡΠΈΡ ΠΌΠ΅ Π΄Π° ΠΆΠΈΠ²Π΅Π΅ΠΌ Ρ ΡΠΎΠ²Π° ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ - Π΄ΠΎΠ±ΡΠ΅ Π΄ΠΎΡΠ»ΠΈ.
ΠΠ°Π·Π²Π°ΠΌ ΡΠ΅ ΠΠ°Π²Π΅Π» Π‘ΠΈΠ²Π°Ρ, Π² DomClick ΡΠ°Π±ΠΎΡΡ Π² Π΅ΠΊΠΈΠΏ, ΠΊΠΎΠΉΡΠΎ ΠΎΡΠ³ΠΎΠ²Π°ΡΡ Π·Π° ΠΏΠΎΠ΄Π΄ΡΡΠΆΠ°Π½Π΅ΡΠΎ Π½Π° Ρ
ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ΡΠΎ Π½Π° Π°Π½Π°Π»ΠΈΡΠΈΡΠ½ΠΈ Π΄Π°Π½Π½ΠΈ. Π£ΡΠ»ΠΎΠ²Π½ΠΎ Π½Π°ΡΠΈΡΠ΅ Π΄Π΅ΠΉΠ½ΠΎΡΡΠΈ ΠΌΠΎΠ³Π°Ρ Π΄Π° Π±ΡΠ΄Π°Ρ ΠΏΡΠΈΠΏΠΈΡΠ°Π½ΠΈ Π½Π° ΠΈΠ½ΠΆΠ΅Π½Π΅ΡΠΈΠ½Π³ Π½Π° Π΄Π°Π½Π½ΠΈ, Π½ΠΎ Π²ΡΡΡΠ½ΠΎΡΡ ΠΎΠ±Ρ
Π²Π°ΡΡΡ Π½Π° Π·Π°Π΄Π°ΡΠΈΡΠ΅ Π΅ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎ-ΡΠΈΡΠΎΠΊ. ΠΠΌΠ° ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΎ ΠΈΠ½ΠΆΠ΅Π½Π΅ΡΡΡΠ²ΠΎ Π½Π° Π΄Π°Π½Π½ΠΈ ETL / ELT, ΠΏΠΎΠ΄Π΄ΡΡΠΆΠΊΠ° ΠΈ Π°Π΄Π°ΠΏΡΠΈΡΠ°Π½Π΅ Π½Π° ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΈ Π·Π° Π°Π½Π°Π»ΠΈΠ· Π½Π° Π΄Π°Π½Π½ΠΈ ΠΈ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠ²Π°Π½Π΅ Π½Π° ΡΠΎΠ±ΡΡΠ²Π΅Π½ΠΈ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΈ. ΠΠΎ-ΡΠΏΠ΅ΡΠΈΠ°Π»Π½ΠΎ, Π·Π° ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠ²Π½ΠΎΡΠΎ ΠΎΡΡΠΈΡΠ°Π½Π΅ ΡΠ΅ΡΠΈΡ
ΠΌΠ΅ Π΄Π° ΡΠ΅ βΠΏΡΠ΅ΡΡΡΡΠ²Π°ΠΌΠ΅β, ΡΠ΅ ΠΈΠΌΠ°ΠΌΠ΅ ΠΌΠΎΠ½ΠΎΠ»ΠΈΡ ΠΈ Π΄Π° Π΄Π°Π΄Π΅ΠΌ Π½Π° Π°Π½Π°Π»ΠΈΠ·Π°ΡΠΎΡΠΈΡΠ΅ Π΅Π΄Π½Π° Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ, ΠΊΠΎΡΡΠΎ ΡΠ΅ ΡΡΠ΄ΡΡΠΆΠ° Π²ΡΠΈΡΠΊΠΈ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΈ Π΄Π°Π½Π½ΠΈ.
ΠΠ°ΡΠΎ ΡΡΠ»ΠΎ ΠΎΠ±ΠΌΠΈΡΠ»ΡΡ ΠΌΠ΅ ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ Π²Π°ΡΠΈΠ°Π½ΡΠΈ. ΠΠ΅ΡΠ΅ Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎ Π΄Π° ΡΠ΅ ΠΈΠ·Π³ΡΠ°Π΄ΠΈ ΠΏΡΠ»Π½ΠΎΡΠ΅Π½Π½ΠΎ Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ - Π΄ΠΎΡΠΈ ΡΠ΅ ΠΎΠΏΠΈΡΠ°Ρ ΠΌΠ΅, Π½ΠΎ, ΡΠ΅ΡΡΠ½ΠΎ ΠΊΠ°Π·Π°Π½ΠΎ, Π½Π΅ ΡΡΠΏΡΡ ΠΌΠ΅ Π΄Π° ΡΠ΅ ΡΠΏΡΠΈΡΡΠ΅Π»ΠΈΠΌ Ρ Π΄ΠΎΡΡΠ° ΡΠ΅ΡΡΠΈ ΠΏΡΠΎΠΌΠ΅Π½ΠΈ Π² Π»ΠΎΠ³ΠΈΠΊΠ°ΡΠ° Ρ Π΄ΠΎΡΡΠ° Π±Π°Π²Π΅Π½ ΠΏΡΠΎΡΠ΅Ρ Π½Π° ΠΈΠ·Π³ΡΠ°ΠΆΠ΄Π°Π½Π΅ Π½Π° Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ ΠΈ ΠΏΡΠ°Π²Π΅Π½Π΅ Π½Π° ΠΏΡΠΎΠΌΠ΅Π½ΠΈ Π² Π½Π΅Π³ΠΎ ( Π°ΠΊΠΎ Π½ΡΠΊΠΎΠΉ Π΅ ΡΡΠΏΡΠ», Π½Π°ΠΏΠΈΡΠ΅ΡΠ΅ Π² ΠΊΠΎΠΌΠ΅Π½ΡΠ°ΡΠΈΡΠ΅ ΠΊΠ°ΠΊ). ΠΠΈΡ ΡΠ΅ ΠΌΠΎΠ³Π»ΠΈ Π΄Π° ΠΊΠ°ΠΆΠ΅ΡΠ΅ Π½Π° Π°Π½Π°Π»ΠΈΠ·Π°ΡΠΎΡΠΈΡΠ΅: βΠΠΎΠΌΡΠ΅ΡΠ°, Π½Π°ΡΡΠ΅ΡΠ΅ Python ΠΈ ΠΎΡΠΈΠ΄Π΅ΡΠ΅ Π½Π° Π°Π½Π°Π»ΠΈΡΠΈΡΠ½ΠΈ Π»ΠΈΠ½ΠΈΠΈβ, Π½ΠΎ ΡΠΎΠ²Π° Π΅ Π΄ΠΎΠΏΡΠ»Π½ΠΈΡΠ΅Π»Π½ΠΎ ΠΈΠ·ΠΈΡΠΊΠ²Π°Π½Π΅ Π·Π° Π½Π°Π±ΠΈΡΠ°Π½Π΅ Π½Π° ΠΏΠ΅ΡΡΠΎΠ½Π°Π» ΠΈ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π°, ΡΠ΅ ΡΠΎΠ²Π° ΡΡΡΠ±Π²Π° Π΄Π° ΡΠ΅ ΠΈΠ·Π±ΡΠ³Π²Π°, Π°ΠΊΠΎ Π΅ Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎ. Π Π΅ΡΠΈΡ ΠΌΠ΅ Π΄Π° ΠΎΠΏΠΈΡΠ°ΠΌΠ΅ Ρ ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΡΡΠ° FDW (Foreign Data Wrapper): Π²ΡΡΡΠ½ΠΎΡΡ ΡΠΎΠ²Π° Π΅ ΡΡΠ°Π½Π΄Π°ΡΡΠ΅Π½ dblink, ΠΊΠΎΠΉΡΠΎ Π΅ Π² ΡΡΠ°Π½Π΄Π°ΡΡΠ° SQL, Π½ΠΎ Ρ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎ-ΡΠ΄ΠΎΠ±Π½ΠΈΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ. ΠΡΠ· ΠΎΡΠ½ΠΎΠ²Π° Π½Π° Π½Π΅Π³ΠΎ Π²Π·Π΅Ρ ΠΌΠ΅ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅, ΠΊΠΎΠ΅ΡΠΎ Π² ΠΊΡΠ°ΠΉΠ½Π° ΡΠΌΠ΅ΡΠΊΠ° ΡΠ΅ Π·Π°ΡΠ²ΡΡΠ΄ΠΈ, ΡΠΏΡΡΡ ΠΌΠ΅ ΡΠ΅ Π½Π° Π½Π΅Π³ΠΎ. ΠΠ΅Π³ΠΎΠ²ΠΈΡΠ΅ ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎΡΡΠΈ ΡΠ° ΡΠ΅ΠΌΠ° Π½Π° ΠΎΡΠ΄Π΅Π»Π½Π° ΡΡΠ°ΡΠΈΡ, Π° ΠΌΠΎΠΆΠ΅ Π±ΠΈ ΠΈ ΠΏΠΎΠ²Π΅ΡΠ΅ ΠΎΡ Π΅Π΄Π½Π°, Π·Π°ΡΠΎΡΠΎ ΠΈΡΠΊΠ°ΠΌ Π΄Π° Π³ΠΎΠ²ΠΎΡΡ Π·Π° ΠΌΠ½ΠΎΠ³ΠΎ: ΠΎΡ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·ΠΈΡΠ°Π½Π΅ΡΠΎ Π½Π° ΡΡ Π΅ΠΌΠ°ΡΠ° Π½Π° Π±Π°Π·Π°ΡΠ° Π΄Π°Π½Π½ΠΈ Π΄ΠΎ ΠΊΠΎΠ½ΡΡΠΎΠ»Π° Π½Π° Π΄ΠΎΡΡΡΠΏΠ° ΠΈ ΠΎΠ±Π΅Π·Π»ΠΈΡΠ°Π²Π°Π½Π΅ΡΠΎ Π½Π° Π»ΠΈΡΠ½ΠΈ Π΄Π°Π½Π½ΠΈ. Π’ΡΡΠ±Π²Π° ΡΡΡΠΎ Π΄Π° ΡΠ΅ ΠΎΡΠ±Π΅Π»Π΅ΠΆΠΈ, ΡΠ΅ ΡΠΎΠ²Π° ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ Π½Π΅ Π΅ Π·Π°ΠΌΠ΅ΡΡΠΈΡΠ΅Π» Π½Π° ΡΠ΅Π°Π»Π½ΠΈ Π°Π½Π°Π»ΠΈΡΠΈΡΠ½ΠΈ Π±Π°Π·ΠΈ Π΄Π°Π½Π½ΠΈ ΠΈ Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ°, ΡΠΎ ΡΠ΅ΡΠ°Π²Π° ΡΠ°ΠΌΠΎ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ΅Π½ ΠΏΡΠΎΠ±Π»Π΅ΠΌ.
ΠΠ° Π½Π°ΠΉ-Π²ΠΈΡΠΎΠΊΠΎ Π½ΠΈΠ²ΠΎ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° ΡΠ°ΠΊΠ°:
ΠΠΌΠ° 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 Π½ΠΈΠ·).
ΠΠ΅ΠΊΠ° ΠΎΡΠΈΠ΄Π΅ΠΌ ΠΌΠ°Π»ΠΊΠΎ ΠΏΠΎ-Π΄Π°Π»Π΅Ρ ΠΈ Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π½ΡΠΊΠΎΠ»ΠΊΠΎ ΡΠΈΠ»ΡΡΡΠ° ΠΊΡΠΌ Π½Π°ΡΠ°ΡΠ° Π·Π°ΡΠ²ΠΊΠ°: Π΅Π΄ΠΈΠ½ ΠΏΠΎ Π±ΡΠ»Π΅Π²Π° ΠΏΠΎΠ»Π΅, Π΅Π΄Π½ΠΎ ΠΏΠΎ Π²Ρ ΠΊΠ»Π΅ΠΉΠΌΠΎΡΠΎ Π½Π° ΠΈΠ½ΡΠ΅ΡΠ²Π°Π» ΠΈ Π΅Π΄ΠΈΠ½ ΠΏΠΎ 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) ΠΈ Π΄Π° ΠΈΠ·Π²ΡΡΡΠΈ Π°Π³ΡΠ΅Π³ΠΈΡΠ°Π½Π΅ ΠΏΠΎ-ΠΊΡΡΠ½ΠΎ. ΠΠ»ΡΡΡΡ ΠΊΡΠΌ ΡΡΠΏΠ΅Ρ Π° Π΅ Π΄Π° Π½Π°ΠΏΠΈΡΠ΅ΡΠ΅ Π·Π°ΡΠ²ΠΊΠ°, ΡΠ°ΠΊΠ° ΡΠ΅ ΡΠΈΠ»ΡΡΠΈΡΠ΅ Π΄Π° ΡΠ΅ ΠΏΡΠ΅Π΄Π°Π²Π°Ρ Π½Π° ΠΎΡΠ΄Π°Π»Π΅ΡΠ΅Π½Π°ΡΠ° ΠΌΠ°ΡΠΈΠ½Π°, Π° Π½ΠΈΠ΅ Π΄Π° ΠΏΠΎΠ»ΡΡΠ°Π²Π°ΠΌΠ΅ ΠΈ ΠΎΠ±ΠΎΠ±ΡΠ°Π²Π°ΠΌΠ΅ ΡΠ°ΠΌΠΎ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΈΡΠ΅ ΡΠ΅Π΄ΠΎΠ²Π΅.
Π’ΠΎΠ²Π° ΡΠ° Π½ΡΠΊΠ°ΠΊΠ²ΠΈ Π±ΡΠ»Π΅Π²ΠΈ Π³Π»ΡΠΏΠΎΡΡΠΈ
Π‘ Π±ΡΠ»Π΅Π²ΠΈΡΠ΅ ΠΏΠΎΠ»Π΅ΡΠ° Π²ΡΠΈΡΠΊΠΎ Π΅ ΠΏΡΠΎΡΡΠΎ. Π ΠΏΡΡΠ²ΠΎΠ½Π°ΡΠ°Π»Π½ΠΎΡΠΎ Π·Π°ΠΏΠΈΡΠ²Π°Π½Π΅ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡΡ ΡΠ΅ Π΄ΡΠ»ΠΆΠΈ Π½Π° ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠ° 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 ΡΠ°Π·Π»ΠΈΡΠ΅Π½ ΠΎΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠ° = ΡΠΎΠ·ΠΈ, ΠΊΠΎΠΉΡΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ°Π±ΠΎΡΠΈ Ρ Π½ΡΠ»Π΅Π²Π°ΡΠ° ΡΡΠΎΠΉΠ½ΠΎΡΡ. ΠΠ·Π½Π°ΡΠ°Π²Π°, ΡΠ΅ Π½Π΅ Π΅ Π²ΡΡΠ½ΠΎ Π²ΡΠ² ΡΠΈΠ»ΡΡΡΠ° ΡΠ΅ ΠΎΡΡΠ°Π²ΠΈ ΡΡΠΎΠΉΠ½ΠΎΡΡΠΈΡΠ΅ False ΠΈ Null, Π΄ΠΎΠΊΠ°ΡΠΎ != ΠΡΡΠ½ΠΎ ΡΠ΅ ΠΎΡΡΠ°Π²ΠΈ ΡΠ°ΠΌΠΎ False ΡΡΠΎΠΉΠ½ΠΎΡΡΠΈ. Π‘Π»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»Π½ΠΎ ΠΏΡΠΈ ΡΠΌΡΠ½Π° Π½Π° ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠ° Π½Π΅ ΡΡΡΠ±Π²Π° Π΄Π° ΠΏΠΎΠ΄Π°Π΄Π΅ΡΠ΅ Π΄Π²Π΅ ΡΡΠ»ΠΎΠ²ΠΈΡ ΠΊΡΠΌ ΡΠΈΠ»ΡΡΡΠ° Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠ° OR, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, WHERE (ΠΊΠΎΠ»Π° != True) ΠΠΠ (ΠΊΠΎΠ»Π° Π΅ Π½ΡΠ»Π°).
Π‘ ΡΠ°Π·Π±ΡΠ°Π½ΠΎ Π±ΡΠ»Π΅Π²ΠΎ, ΠΏΡΠΎΠ΄ΡΠ»ΠΆΠ°Π²Π°ΠΌΠ΅ Π½Π°ΠΏΡΠ΅Π΄. ΠΠ΅ΠΆΠ΄ΡΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎ Π½Π΅ΠΊΠ° Π²ΡΡΠ½Π΅ΠΌ ΡΠΈΠ»ΡΡΡΠ° ΠΏΠΎ Π±ΡΠ»Π΅Π²Π° ΡΡΠΎΠΉΠ½ΠΎΡΡ Π² ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»Π½Π°ΡΠ° ΠΌΡ ΡΠΎΡΠΌΠ°, Π·Π° Π΄Π° ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ Π½Π΅Π·Π°Π²ΠΈΡΠΈΠΌΠΎ Π΅ΡΠ΅ΠΊΡΠ° ΠΎΡ Π΄ΡΡΠ³ΠΈ ΠΏΡΠΎΠΌΠ΅Π½ΠΈ.
timestamptz? Ρ Ρ
ΠΠΎ ΠΏΡΠΈΠ½ΡΠΈΠΏ ΡΠ΅ΡΡΠΎ ΡΡΡΠ±Π²Π° Π΄Π° Π΅ΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠΈΡΠ°ΡΠ΅ ΠΊΠ°ΠΊ ΠΏΡΠ°Π²ΠΈΠ»Π½ΠΎ Π΄Π° Π½Π°ΠΏΠΈΡΠ΅ΡΠ΅ Π·Π°ΡΠ²ΠΊΠ°, ΠΊΠΎΡΡΠΎ Π²ΠΊΠ»ΡΡΠ²Π° ΠΎΡΠ΄Π°Π»Π΅ΡΠ΅Π½ΠΈ ΡΡΡΠ²ΡΡΠΈ, ΠΈ Π΅Π΄Π²Π° ΡΠ»Π΅Π΄ ΡΠΎΠ²Π° Π΄Π° ΡΡΡΡΠΈΡΠ΅ ΠΎΠ±ΡΡΠ½Π΅Π½ΠΈΠ΅ Π·Π°ΡΠΎ ΡΠΎΠ²Π° ΡΠ΅ ΡΠ»ΡΡΠ²Π°. ΠΠ½ΠΎΠ³ΠΎ ΠΌΠ°Π»ΠΊΠΎ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ Π·Π° ΡΠΎΠ²Π° ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ Π½Π°ΠΌΠ΅ΡΠΈ Π² ΠΈΠ½ΡΠ΅ΡΠ½Π΅Ρ. Π ΡΠ°ΠΊΠ°, Π² Π΅ΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠΈ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡ ΠΌΠ΅, ΡΠ΅ ΡΠΈΠ»ΡΡΡ Ρ ΡΠΈΠΊΡΠΈΡΠ°Π½Π° Π΄Π°ΡΠ° Π»Π΅ΡΠΈ Π΄ΠΎ ΠΎΡΠ΄Π°Π»Π΅ΡΠ΅Π½ ΡΡΡΠ²ΡΡ Ρ Π³ΡΡΠΌ ΠΈ ΡΡΡΡΡΠΊ, Π½ΠΎ ΠΊΠΎΠ³Π°ΡΠΎ ΠΈΡΠΊΠ°ΠΌΠ΅ Π΄Π° Π·Π°Π΄Π°Π΄Π΅ΠΌ Π΄Π°ΡΠ°ΡΠ° Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ½ΠΎ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ now() ΠΈΠ»ΠΈ CURRENT_DATE, ΡΠΎΠ²Π° Π½Π΅ ΡΠ΅ ΡΠ»ΡΡΠ²Π°. Π Π½Π°ΡΠΈΡ ΠΏΡΠΈΠΌΠ΅Ρ ΡΠΌΠ΅ Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ ΡΠΈΠ»ΡΡΡ, ΡΠ°ΠΊΠ° ΡΠ΅ ΠΊΠΎΠ»ΠΎΠ½Π°ΡΠ° created_at Π΄Π° ΡΡΠ΄ΡΡΠΆΠ° Π΄Π°Π½Π½ΠΈ Π·Π° ΡΠΎΡΠ½ΠΎ 1 ΠΌΠ΅ΡΠ΅Ρ Π² ΠΌΠΈΠ½Π°Π»ΠΎΡΠΎ (ΠΠΠΠΠ£ 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 ΠΏΡΡΠΈ ΠΏΠΎ-Π±ΡΡΠ·Π°!
ΠΡΠ½ΠΎΠ²ΠΎ Π΅ Π²Π°ΠΆΠ½ΠΎ Π΄Π° Π²Π½ΠΈΠΌΠ°Π²Π°ΡΠ΅ ΡΡΠΊ: ΡΠΈΠΏΡΡ Π΄Π°Π½Π½ΠΈ Π² ΠΏΠΎΠ΄Π·Π°ΡΠ²ΠΊΠ°ΡΠ° ΡΡΡΠ±Π²Π° Π΄Π° Π΅ ΡΡΡΠΈΡΡ ΠΊΠ°ΡΠΎ ΡΠΎΠ·ΠΈ Π½Π° ΠΏΠΎΠ»Π΅ΡΠΎ, ΠΏΠΎ ΠΊΠΎΠ΅ΡΠΎ ΡΠΈΠ»ΡΡΠΈΡΠ°ΠΌΠ΅, Π² ΠΏΡΠΎΡΠΈΠ²Π΅Π½ ΡΠ»ΡΡΠ°ΠΉ ΠΏΠ»Π°Π½ΠΎΠ²ΠΈΡΡ ΡΠ΅ ΡΠ΅ΡΠΈ, ΡΠ΅ ΡΡΠΉ ΠΊΠ°ΡΠΎ ΡΠΈΠΏΠΎΠ²Π΅ΡΠ΅ ΡΠ° ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ ΠΈ Π΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΡΡΠ²ΠΎ Π΄Π° ΠΏΠΎΠ»ΡΡΠΈΡΠ΅ Π²ΡΠΈΡΠΊΠΈ Π΄Π°Π½Π½ΠΈ ΠΈ Π³ΠΈ ΡΠΈΠ»ΡΡΠΈΡΠ°ΠΉΡΠ΅ Π»ΠΎΠΊΠ°Π»Π½ΠΎ.
ΠΠ΅ΠΊΠ° Π²ΡΡΠ½Π΅ΠΌ ΡΠΈΠ»ΡΡΡΠ° ΠΏΠΎ Π΄Π°ΡΠ° ΠΊΡΠΌ ΠΏΡΡΠ²ΠΎΠ½Π°ΡΠ°Π»Π½Π°ΡΠ° ΠΌΡ ΡΡΠΎΠΉΠ½ΠΎΡΡ.
Π€ΡΠ΅Π΄ΠΈ ΡΡΠ΅ΡΡ jsonb
ΠΠ°ΡΠΎ ΡΡΠ»ΠΎ Π±ΡΠ»Π΅Π²ΠΈΡΠ΅ ΠΏΠΎΠ»Π΅ΡΠ° ΠΈ Π΄Π°ΡΠΈ Π²Π΅ΡΠ΅ Π΄ΠΎΡΡΠ°ΡΡΡΠ½ΠΎ ΡΡΠΊΠΎΡΠΈΡ Π° Π½Π°ΡΠ°ΡΠ° Π·Π°ΡΠ²ΠΊΠ°, Π½ΠΎ ΠΈΠΌΠ°ΡΠ΅ ΠΎΡΠ΅ Π΅Π΄ΠΈΠ½ ΡΠΈΠΏ Π΄Π°Π½Π½ΠΈ. ΠΠΈΡΠΊΠ°ΡΠ° Ρ ΡΠΈΠ»ΡΡΠΈΡΠ°Π½Π΅ΡΠΎ ΠΏΠΎ Π½Π΅Π³ΠΎ, ΡΠ΅ΡΡΠ½ΠΎ ΠΊΠ°Π·Π°Π½ΠΎ, Π²ΡΠ΅ ΠΎΡΠ΅ Π½Π΅ Π΅ ΠΏΡΠΈΠΊΠ»ΡΡΠΈΠ»Π°, Π²ΡΠΏΡΠ΅ΠΊΠΈ ΡΠ΅ ΠΈ ΡΡΠΊ ΠΈΠΌΠ° ΡΡΠΏΠ΅Ρ ΠΈ. Π ΡΠ°ΠΊΠ°, Π΅ΡΠΎ ΠΊΠ°ΠΊ ΡΡΠΏΡΡ ΠΌΠ΅ Π΄Π° ΠΏΡΠ΅ΠΌΠΈΠ½Π΅ΠΌ ΡΠΈΠ»ΡΡΡΠ° 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 ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅, 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 <(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