ΠΠΈΠΊΡΠΎΡΠ΅ΡΠ²ΠΈΡΠ½Π°ΡΠ° Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ°, ΠΊΠ°ΠΊΠΎ ΠΈ ΡΓ¨ Π½Π° ΠΎΠ²ΠΎΡ ΡΠ²Π΅Ρ, ΠΈΠΌΠ° ΡΠ²ΠΎΠΈ Π΄ΠΎΠ±ΡΠΈΡΠ΅ ΠΈ Π»ΠΎΡΠΈΡΠ΅ ΡΡΡΠ°Π½ΠΈ. ΠΠ΅ΠΊΠΎΠΈ ΠΏΡΠΎΡΠ΅ΡΠΈ ΡΡΠ°Π½ΡΠ²Π°Π°Ρ ΠΏΠΎΠ»Π΅ΡΠ½ΠΈ ΡΠΎ Π½Π΅Π³ΠΎ, Π΄ΡΡΠ³ΠΈ ΠΏΠΎΡΠ΅ΡΠΊΠΈ. Π Π·Π°ΡΠ°Π΄ΠΈ Π±ΡΠ·ΠΈΠ½Π°ΡΠ° Π½Π° ΠΏΡΠΎΠΌΠ΅Π½ΠΈΡΠ΅ ΠΈ ΠΏΠΎΠ΄ΠΎΠ±ΡΠ°ΡΠ° ΠΏΡΠΈΡΠΏΠΎΡΠΎΠ±Π»ΠΈΠ²ΠΎΡΡ, ΡΡΠ΅Π±Π° Π΄Π° ΡΠ΅ ΠΆΡΡΠ²ΡΠ²Π°ΡΠ΅. ΠΠ΄Π΅Π½ ΠΎΠ΄ Π½ΠΈΠ² Π΅ Π·Π³ΠΎΠ»Π΅ΠΌΠ΅Π½Π°ΡΠ° ΡΠ»ΠΎΠΆΠ΅Π½ΠΎΡΡ Π½Π° Π°Π½Π°Π»ΠΈΡΠΈΠΊΠ°ΡΠ°. ΠΠΊΠΎ Π²ΠΎ ΠΌΠΎΠ½ΠΎΠ»ΠΈΡ ΡΠ΅Π»Π°ΡΠ° ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠ²Π½Π° Π°Π½Π°Π»ΠΈΡΠΈΠΊΠ° ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΡΠ²Π΅Π΄Π΅ Π½Π° SQL Π±Π°ΡΠ°ΡΠ° Π΄ΠΎ Π°Π½Π°Π»ΠΈΡΠΈΡΠΊΠ° ΡΠ΅ΠΏΠ»ΠΈΠΊΠ°, ΡΠΎΠ³Π°Ρ Π²ΠΎ ΠΌΡΠ»ΡΠΈΡΠ΅ΡΠ²ΠΈΡΠ½Π°ΡΠ° Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ° ΡΠ΅ΠΊΠΎΡΠ° ΡΡΠ»ΡΠ³Π° ΠΈΠΌΠ° ΡΠ²ΠΎΡΠ° Π±Π°Π·Π° Π½Π° ΠΏΠΎΠ΄Π°ΡΠΎΡΠΈ ΠΈ ΡΠ΅ ΡΠΈΠ½ΠΈ Π΄Π΅ΠΊΠ° Π΅Π΄Π½ΠΎ Π±Π°ΡΠ°ΡΠ΅ Π½Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ Π½Π°ΠΏΡΠ°Π²ΠΈ (ΠΈΠ»ΠΈ ΠΌΠΎΠΆΠ΅Π±ΠΈ ΠΌΠΎΠΆΠ΅?). ΠΠ° ΠΎΠ½ΠΈΠ΅ ΠΊΠΎΠΈ ΡΠ΅ Π·Π°ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠΈΡΠ°Π½ΠΈ ΠΊΠ°ΠΊΠΎ Π³ΠΎ ΡΠ΅ΡΠΈΠ²ΠΌΠ΅ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΎΡ ΡΠΎ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠ²Π½Π°ΡΠ° Π°Π½Π°Π»ΠΈΡΠΈΠΊΠ° Π²ΠΎ Π½Π°ΡΠ°ΡΠ° ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΡΠ° ΠΈ ΠΊΠ°ΠΊΠΎ Π½Π°ΡΡΠΈΠ²ΠΌΠ΅ Π΄Π° ΠΆΠΈΠ²Π΅Π΅ΠΌΠ΅ ΡΠΎ ΠΎΠ²Π° ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ - Π΄ΠΎΠ±ΡΠ΅Π΄ΠΎΡΠ΄Π΅.
ΠΠ°Ρ ΡΠ΅ Π²ΠΈΠΊΠ°ΠΌ ΠΠ°Π²Π΅Π» Π‘ΠΈΠ²Π°Ρ, Π²ΠΎ DomClick ΡΠ°Π±ΠΎΡΠ°ΠΌ Π²ΠΎ ΡΠΈΠΌ ΠΊΠΎΡ Π΅ ΠΎΠ΄Π³ΠΎΠ²ΠΎΡΠ΅Π½ Π·Π° ΠΎΠ΄ΡΠΆΡΠ²Π°ΡΠ΅ Π½Π° ΡΠΊΠ»Π°Π΄ΠΈΡΡΠ΅ΡΠΎ Π·Π° Π°Π½Π°Π»ΠΈΡΠΈΡΠΊΠΈ ΠΏΠΎΠ΄Π°ΡΠΎΡΠΈ. ΠΠΎΠ½Π²Π΅Π½ΡΠΈΠΎΠ½Π°Π»Π½ΠΎ, Π½Π°ΡΠΈΡΠ΅ Π°ΠΊΡΠΈΠ²Π½ΠΎΡΡΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΠΊΠ»Π°ΡΠΈΡΠΈΡΠΈΡΠ°Π°Ρ ΠΊΠ°ΠΊΠΎ ΠΈΠ½ΠΆΠ΅Π½Π΅ΡΡΡΠ²ΠΎ Π½Π° ΠΏΠΎΠ΄Π°ΡΠΎΡΠΈ, Π½ΠΎ, Π²ΡΡΡΠ½ΠΎΡΡ, ΠΎΠΏΡΠ΅Π³ΠΎΡ Π½Π° Π·Π°Π΄Π°ΡΠΈ Π΅ ΠΌΠ½ΠΎΠ³Ρ ΠΏΠΎΡΠΈΡΠΎΠΊ. ΠΠΎΡΡΠΎΡΠ°Ρ ETL/ELT ΡΡΠ°Π½Π΄Π°ΡΠ΄ Π·Π° ΠΈΠ½ΠΆΠ΅Π½Π΅ΡΡΡΠ²ΠΎ Π½Π° ΠΏΠΎΠ΄Π°ΡΠΎΡΠΈ, ΠΏΠΎΠ΄Π΄ΡΡΠΊΠ° ΠΈ Π°Π΄Π°ΠΏΡΠ°ΡΠΈΡΠ° Π½Π° Π°Π»Π°ΡΠΊΠΈ Π·Π° Π°Π½Π°Π»ΠΈΠ·Π° Π½Π° ΠΏΠΎΠ΄Π°ΡΠΎΡΠΈ ΠΈ ΡΠ°Π·Π²ΠΎΡ Π½Π° ΡΠΎΠΏΡΡΠ²Π΅Π½ΠΈ Π°Π»Π°ΡΠΊΠΈ. ΠΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎ, Π·Π° ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠ²Π½ΠΎΡΠΎ ΠΈΠ·Π²Π΅ΡΡΡΠ²Π°ΡΠ΅, ΡΠ΅ΡΠΈΠ²ΠΌΠ΅ Π΄Π° ΡΠ΅ βΠΏΡΠ΅ΠΏΡΠ°Π²Π°ΠΌΠ΅β Π΄Π΅ΠΊΠ° ΠΈΠΌΠ°ΠΌΠ΅ ΠΌΠΎΠ½ΠΎΠ»ΠΈΡ ΠΈ Π΄Π° ΠΈΠΌ Π΄Π°Π΄Π΅ΠΌΠ΅ Π½Π° Π°Π½Π°Π»ΠΈΡΠΈΡΠ°ΡΠΈΡΠ΅ Π΅Π΄Π½Π° Π±Π°Π·Π° Π½Π° ΠΏΠΎΠ΄Π°ΡΠΎΡΠΈ ΡΡΠΎ ΡΠ΅ Π³ΠΈ ΡΠΎΠ΄ΡΠΆΠΈ ΡΠΈΡΠ΅ ΠΏΠΎΠ΄Π°ΡΠΎΡΠΈ ΡΡΠΎ ΠΈΠΌ ΡΠ΅ ΠΏΠΎΡΡΠ΅Π±Π½ΠΈ.
ΠΠΎ ΠΏΡΠΈΠ½ΡΠΈΠΏ, ΡΠ°Π·Π³Π»Π΅Π΄Π°Π²ΠΌΠ΅ ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ ΠΎΠΏΡΠΈΠΈ. ΠΠ΅ΡΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π΄Π° ΡΠ΅ ΠΈΠ·Π³ΡΠ°Π΄ΠΈ ΠΏΠΎΠ»Π½ΠΎΠΏΡΠ°Π²Π½ΠΎ ΡΠΊΠ»Π°Π΄ΠΈΡΡΠ΅ - Π΄ΡΡΠΈ ΠΈ ΡΠ΅ ΠΎΠ±ΠΈΠ΄ΠΎΠ²ΠΌΠ΅, Π½ΠΎ, Π΄Π° Π±ΠΈΠ΄Π°ΠΌ ΠΈΡΠΊΡΠ΅Π½, Π½Π΅ ΡΡΠΏΠ΅Π°Π²ΠΌΠ΅ Π΄Π° ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡΠ°ΠΌΠ΅ ΠΏΡΠΈΠ»ΠΈΡΠ½ΠΎ ΡΠ΅ΡΡΠΈ ΠΏΡΠΎΠΌΠ΅Π½ΠΈ Π²ΠΎ Π»ΠΎΠ³ΠΈΠΊΠ°ΡΠ° ΡΠΎ ΠΏΡΠΈΠ»ΠΈΡΠ½ΠΎ Π±Π°Π²Π½ΠΈΠΎΡ ΠΏΡΠΎΡΠ΅Ρ Π½Π° Π³ΡΠ°Π΄Π΅ΡΠ΅ ΡΠΊΠ»Π°Π΄ΠΈΡΡΠ΅ ΠΈ ΠΏΡΠ°Π²Π΅ΡΠ΅ ΠΏΡΠΎΠΌΠ΅Π½ΠΈ Π²ΠΎ Π½Π΅Π³ΠΎ (Π°ΠΊΠΎ Π½Π΅ΠΊΠΎΡ ΡΡΠΏΠ΅Π΅ , ΠΏΠΈΡΠ΅ΡΠ΅ Π²ΠΎ ΠΊΠΎΠΌΠ΅Π½ΡΠ°Ρ ΠΊΠ°ΠΊΠΎ). ΠΠ° Π°Π½Π°Π»ΠΈΡΠΈΡΠ°ΡΠΈΡΠ΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΈΠΌ ΡΠ΅ ΠΊΠ°ΠΆΠ΅: βΠΠΎΠΌΡΠΈ, Π½Π°ΡΡΠ΅ΡΠ΅ ΠΏΠΈΡΠΎΠ½ ΠΈ ΠΎΠ΄Π΅ΡΠ΅ Π½Π° Π°Π½Π°Π»ΠΈΡΠΈΡΠΊΠΈ ΡΠ΅ΠΏΠ»ΠΈΠΊΠΈβ, Π½ΠΎ ΠΎΠ²Π° Π΅ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»Π΅Π½ ΡΡΠ»ΠΎΠ² Π·Π° ΡΠ΅Π³ΡΡΡΠΈΡΠ°ΡΠ΅ ΠΈ ΡΠ΅ ΡΠΈΠ½Π΅ΡΠ΅ Π΄Π΅ΠΊΠ° ΠΎΠ²Π° ΡΡΠ΅Π±Π° Π΄Π° ΡΠ΅ ΠΈΠ·Π±Π΅Π³Π½Π΅ Π°ΠΊΠΎ Π΅ ΠΌΠΎΠΆΠ½ΠΎ. Π Π΅ΡΠΈΠ²ΠΌΠ΅ Π΄Π° ΡΠ΅ ΠΎΠ±ΠΈΠ΄Π΅ΠΌΠ΅ Π΄Π° ΡΠ° ΠΊΠΎΡΠΈΡΡΠΈΠΌΠ΅ ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΡΠ°ΡΠ° 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).
ΠΡΠ΄Π΅ Π΄Π° ΠΎΠ΄ΠΈΠΌΠ΅ ΠΌΠ°Π»ΠΊΡ ΠΏΠΎΠ΄Π°Π»Π΅ΠΊΡ ΠΈ Π΄Π° Π΄ΠΎΠ΄Π°Π΄Π΅ΠΌΠ΅ Π½Π΅ΠΊΠΎΠ»ΠΊΡ ΡΠΈΠ»ΡΡΠΈ Π½Π° Π½Π°ΡΠ΅ΡΠΎ Π±Π°ΡΠ°ΡΠ΅: Π΅Π΄Π΅Π½ Π·Π° 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