PostgreSQL Antipatterns: Π²Ρ€Π΅Π΄Π½ΠΈ JOIN ΠΈ OR

ΠŸΠ°Π·Π΅Ρ‚Π΅ сС ΠΎΡ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ носят Π±ΡƒΡ„Π΅Ρ€ΠΈ...
Използвайки ΠΌΠ°Π»ΠΊΠ° заявка ΠΊΠ°Ρ‚ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π½Π΅ΠΊΠ° Π΄Π° Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ някои унивСрсални ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈ Π·Π° ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€Π°Π½Π΅ Π½Π° заявки Π² PostgreSQL. Π”Π°Π»ΠΈ Ρ‰Π΅ Π³ΠΈ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ ΠΈΠ»ΠΈ Π½Π΅, зависи ΠΎΡ‚ вас, Π½ΠΎ си струва Π΄Π° Π·Π½Π°Π΅Ρ‚Π΅ Π·Π° тях.

Π’ някои слСдващи вСрсии Π½Π° PG ситуацията ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ, ΠΊΠΎΠ³Π°Ρ‚ΠΎ ΠΏΠ»Π°Π½ΠΈΡ€ΠΎΠ²Ρ‡ΠΈΠΊΡŠΡ‚ станС ΠΏΠΎ-ΡƒΠΌΠ΅Π½, Π½ΠΎ Π·Π° 9.4/9.6 ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° ΠΏΡ€ΠΈΠ±Π»ΠΈΠ·ΠΈΡ‚Π΅Π»Π½ΠΎ ΡΡŠΡ‰ΠΎΡ‚ΠΎ, ΠΊΠ°ΠΊΡ‚ΠΎ Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈΡ‚Π΅ Ρ‚ΡƒΠΊ.

НСка Π²Π·Π΅ΠΌΠ΅ΠΌ Π΅Π΄Π½Π° ΠΌΠ½ΠΎΠ³ΠΎ Ρ€Π΅Π°Π»Π½Π° ΠΌΠΎΠ»Π±Π°:

SELECT
  TRUE
FROM
  "Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚" d
INNER JOIN
  "Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅" doc_ex
    USING("@Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚")
INNER JOIN
  "Π’ΠΈΠΏΠ”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°" t_doc ON
    t_doc."@Π’ΠΈΠΏΠ”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°" = d."Π’ΠΈΠΏΠ”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°"
WHERE
  (d."Π›ΠΈΡ†ΠΎ3" = 19091 or d."Π‘ΠΎΡ‚Ρ€ΡƒΠ΄Π½ΠΈΠΊ" = 19091) AND
  d."$Π§Π΅Ρ€Π½ΠΎΠ²ΠΈΠΊ" IS NULL AND
  d."Π£Π΄Π°Π»Π΅Π½" IS NOT TRUE AND
  doc_ex."БостояниС"[1] IS TRUE AND
  t_doc."Π’ΠΈΠΏΠ”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°" = 'ΠŸΠ»Π°Π½Π Π°Π±ΠΎΡ‚'
LIMIT 1;

относно ΠΈΠΌΠ΅Π½Π°Ρ‚Π° Π½Π° Ρ‚Π°Π±Π»ΠΈΡ†ΠΈ ΠΈ ΠΏΠΎΠ»Π΅Ρ‚Π°β€žΠ ΡƒΡΠΊΠΈΡ‚Π΅β€œ ΠΈΠΌΠ΅Π½Π° Π½Π° ΠΏΠΎΠ»Π΅Ρ‚Π° ΠΈ Ρ‚Π°Π±Π»ΠΈΡ†ΠΈ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° сС Ρ‚Ρ€Π΅Ρ‚ΠΈΡ€Π°Ρ‚ ΠΏΠΎ Ρ€Π°Π·Π»ΠΈΡ‡Π΅Π½ Π½Π°Ρ‡ΠΈΠ½, Π½ΠΎ Ρ‚ΠΎΠ²Π° Π΅ Π²ΡŠΠΏΡ€ΠΎΡ Π½Π° вкус. Въй ΠΊΠ°Ρ‚ΠΎ Ρ‚ΡƒΠΊ Π² Tensor няма чуТдСстранни Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΡ†ΠΈ ΠΈ PostgreSQL Π½ΠΈ позволява Π΄Π° Π΄Π°Π²Π°ΠΌΠ΅ ΠΈΠΌΠ΅Π½Π° Π΄ΠΎΡ€ΠΈ Π² ΠΉΠ΅Ρ€ΠΎΠ³Π»ΠΈΡ„ΠΈ, Π°ΠΊΠΎ Ρ‚Π΅ са ΠΎΠ³Ρ€Π°Π΄Π΅Π½ΠΎ Π² ΠΊΠ°Π²ΠΈΡ‡ΠΊΠΈ, Ρ‚ΠΎΠ³Π°Π²Π° ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡ΠΈΡ‚Π°ΠΌΠ΅ Π΄Π° Π½Π°Π·ΠΎΠ²Π°Π²Π°ΠΌΠ΅ ΠΎΠ±Π΅ΠΊΡ‚ΠΈΡ‚Π΅ нСдвусмислСно ΠΈ ясно, Π·Π° Π΄Π° няма разминавания.
НСка Π΄Π° Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ получСния ΠΏΠ»Π°Π½:
PostgreSQL Antipatterns: Π²Ρ€Π΅Π΄Π½ΠΈ JOIN ΠΈ OR
[Π²ΠΈΠΆΡ‚Π΅ expand.tensor.ru]

144ms ΠΈ ΠΏΠΎΡ‡Ρ‚ΠΈ 53K Π±ΡƒΡ„Π΅Ρ€ΠΈ - тоСст ΠΏΠΎΠ²Π΅Ρ‡Π΅ ΠΎΡ‚ 400MB Π΄Π°Π½Π½ΠΈ! И Π½ΠΈΠ΅ Ρ‰Π΅ ΠΈΠΌΠ°ΠΌΠ΅ ΠΊΡŠΡΠΌΠ΅Ρ‚, Π°ΠΊΠΎ всички Ρ‚Π΅ са Π² кСша Π΄ΠΎ ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° Π½Π° Π½Π°ΡˆΠ°Ρ‚Π° заявка, Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π΅Π½ случай Ρ‰Π΅ ΠΎΡ‚Π½Π΅ΠΌΠ΅ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ²Π΅Ρ‡Π΅ Π²Ρ€Π΅ΠΌΠ΅ ΠΏΡ€ΠΈ Ρ‡Π΅Ρ‚Π΅Π½Π΅ ΠΎΡ‚ диск.

ΠΠ»Π³ΠΎΡ€ΠΈΡ‚ΡŠΠΌΡŠΡ‚ Π΅ Π½Π°ΠΉ-Π²Π°ΠΆΠ΅Π½!

Π—Π° Π΄Π° ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€Π°Ρ‚Π΅ ΠΏΠΎ някакъв Π½Π°Ρ‡ΠΈΠ½ всяка заявка, ΠΏΡŠΡ€Π²ΠΎ трябва Π΄Π° Ρ€Π°Π·Π±Π΅Ρ€Π΅Ρ‚Π΅ ΠΊΠ°ΠΊΠ²ΠΎ трябва Π΄Π° ΠΏΡ€Π°Π²ΠΈ.
НСка засСга оставим Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° самата структура Π½Π° Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ извън ΠΎΠ±Ρ…Π²Π°Ρ‚Π° Π½Π° Ρ‚Π°Π·ΠΈ статия ΠΈ сС съгласим, Ρ‡Π΅ ΠΌΠΎΠΆΠ΅ΠΌ сравнитСлно β€žΠ΅Π²Ρ‚ΠΈΠ½ΠΎβ€œ ΠΏΡ€Π΅Π½Π°ΠΏΠΈΡˆΠ΅Ρ‚Π΅ заявката ΠΈ/ΠΈΠ»ΠΈ Ρ‚ΡŠΡ€ΠΊΠ°Π»ΡΠΌΠ΅ Π²ΡŠΡ€Ρ…Ρƒ основата някои ΠΎΡ‚ Π½Π΅Ρ‰Π°Ρ‚Π°, ΠΎΡ‚ ΠΊΠΎΠΈΡ‚ΠΎ сС Π½ΡƒΠΆΠ΄Π°Π΅ΠΌ ИндСкси.

Π’Π°ΠΊΠ° Ρ‡Π΅ ΠΌΠΎΠ»Π±Π°Ρ‚Π°:
β€” провСрява ΡΡŠΡ‰Π΅ΡΡ‚Π²ΡƒΠ²Π°Π½Π΅Ρ‚ΠΎ Π½Π° ΠΏΠΎΠ½Π΅ някакъв Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚
- Π² Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡ‚ΠΎ Π½ΠΈ ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅ ΠΈ ΠΎΡ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ Π²ΠΈΠ΄
- ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ Π°Π²Ρ‚ΠΎΡ€ ΠΈΠ»ΠΈ ΠΈΠ·ΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π» Π΅ слуТитСлят, ΠΎΡ‚ ΠΊΠΎΠΉΡ‚ΠΎ сС Π½ΡƒΠΆΠ΄Π°Π΅ΠΌ

ПРИБΠͺΠ•Π”Π˜ΠΠ•ΠΠ• + ΠžΠ“Π ΠΠΠ˜Π§Π•ΠΠ˜Π• 1

Доста чСсто Π·Π° Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° Π΅ ΠΏΠΎ-лСсно Π΄Π° напишС заявка, ΠΏΡ€ΠΈ която ΠΏΡŠΡ€Π²ΠΎ сС обСдиняват голям Π±Ρ€ΠΎΠΉ Ρ‚Π°Π±Π»ΠΈΡ†ΠΈ ΠΈ слСд Ρ‚ΠΎΠ²Π° остава само Π΅Π΄ΠΈΠ½ запис ΠΎΡ‚ цСлия Ρ‚ΠΎΠ·ΠΈ Π½Π°Π±ΠΎΡ€. Но ΠΏΠΎ-лСсно Π·Π° Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° Π½Π΅ ΠΎΠ·Π½Π°Ρ‡Π°Π²Π° ΠΏΠΎ-Π΅Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎ Π·Π° Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ.
Π’ нашия случай имашС само 3 маси - ΠΈ какъв Π΅ Π΅Ρ„Π΅ΠΊΡ‚ΡŠΡ‚...

НСка ΠΏΡŠΡ€Π²ΠΎ Π΄Π° сС ΠΎΡ‚ΡŠΡ€Π²Π΅ΠΌ ΠΎΡ‚ Π²Ρ€ΡŠΠ·ΠΊΠ°Ρ‚Π° с Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π° β€žΠ’ΠΈΠΏ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚β€œ ΠΈ Π² ΡΡŠΡ‰ΠΎΡ‚ΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π΄Π° ΠΊΠ°ΠΆΠ΅ΠΌ Π½Π° Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ, Ρ‡Π΅ Π½Π°ΡˆΠΈΡΡ‚ Ρ‚ΠΈΠΏΠΎΠ² запис Π΅ ΡƒΠ½ΠΈΠΊΠ°Π»Π΅Π½ (Π·Π½Π°Π΅ΠΌ Ρ‚ΠΎΠ²Π°, Π½ΠΎ ΠΏΠ»Π°Π½ΠΈΡ€ΠΎΠ²Ρ‡ΠΈΠΊΡŠΡ‚ всС ΠΎΡ‰Π΅ няма прСдстава):

WITH T AS (
  SELECT
    "@Π’ΠΈΠΏΠ”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°"
  FROM
    "Π’ΠΈΠΏΠ”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°"
  WHERE
    "Π’ΠΈΠΏΠ”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°" = 'ΠŸΠ»Π°Π½Π Π°Π±ΠΎΡ‚'
  LIMIT 1
)
...
WHERE
  d."Π’ΠΈΠΏΠ”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°" = (TABLE T)
...

Π”Π°, Π°ΠΊΠΎ Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π°/CTE сС ΡΡŠΡΡ‚ΠΎΠΈ ΠΎΡ‚ Π΅Π΄Π½ΠΎ ΠΏΠΎΠ»Π΅ Π½Π° Π΅Π΄ΠΈΠ½ запис, Ρ‚ΠΎΠ³Π°Π²Π° Π² PG ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄ΠΎΡ€ΠΈ Π΄Π° ΠΏΠΈΡˆΠ΅Ρ‚Π΅ Ρ‚Π°ΠΊΠ°, вмСсто

d."Π’ΠΈΠΏΠ”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°" = (SELECT "@Π’ΠΈΠΏΠ”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°" FROM T LIMIT 1)

ΠœΡŠΡ€Π·Π΅Π»ΠΈΠ²Π° ΠΎΡ†Π΅Π½ΠΊΠ° Π² заявки Π½Π° PostgreSQL

BitmapOr срСщу UNION

Π’ някои случаи Bitmap Heap Scan Ρ‰Π΅ Π½ΠΈ струва ΠΌΠ½ΠΎΠ³ΠΎ - Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π² Π½Π°ΡˆΠ°Ρ‚Π° ситуация, ΠΊΠΎΠ³Π°Ρ‚ΠΎ доста записи отговарят Π½Π° изискваното условиС. Π Π°Π·Π±Ρ€Π°Ρ…ΠΌΠ΅ Π³ΠΎ, Π·Π°Ρ‰ΠΎΡ‚ΠΎ УсловиСто Π˜Π›Π˜ сС ΠΏΡ€Π΅Π²ΡŠΡ€Π½Π° Π² BitmapOr- опСрация Π² ΠΏΠ»Π°Π½.
Π”Π° сС β€‹β€‹Π²ΡŠΡ€Π½Π΅ΠΌ към ΠΏΡŠΡ€Π²ΠΎΠ½Π°Ρ‡Π°Π»Π½ΠΈΡ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ - трябва Π΄Π° Π½Π°ΠΌΠ΅Ρ€ΠΈΠΌ ΡΡŠΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²Π°Ρ‰ запис Π½Π° всСки ΠΎΡ‚ условията - тоСст няма Π½ΡƒΠΆΠ΄Π° Π΄Π° Ρ‚ΡŠΡ€ΡΠΈΡ‚Π΅ всички 59K записа ΠΈ ΠΏΡ€ΠΈ Π΄Π²Π΅Ρ‚Π΅ условия. Има Π½Π°Ρ‡ΠΈΠ½ Π΄Π° сС ΠΈΠ·Ρ€Π°Π±ΠΎΡ‚ΠΈ Π΅Π΄Π½ΠΎ условиС ΠΈ ΠΎΡ‚ΠΈΠ΄Π΅Ρ‚Π΅ Π½Π° втория само ΠΊΠΎΠ³Π°Ρ‚ΠΎ Π½ΠΈΡ‰ΠΎ Π½Π΅ Π΅ Π½Π°ΠΌΠ΅Ρ€Π΅Π½ΠΎ Π² ΠΏΡŠΡ€Π²ΠΈΡ. БлСдният Π΄ΠΈΠ·Π°ΠΉΠ½ Ρ‰Π΅ Π½ΠΈ ΠΏΠΎΠΌΠΎΠ³Π½Π΅:

(
  SELECT
    ...
  LIMIT 1
)
UNION ALL
(
  SELECT
    ...
  LIMIT 1
)
LIMIT 1

β€žΠ’ΡŠΠ½ΡˆΠ΅Π½β€œ LIMIT 1 Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€Π°, Ρ‡Π΅ Ρ‚ΡŠΡ€ΡΠ΅Π½Π΅Ρ‚ΠΎ ΠΏΡ€ΠΈΠΊΠ»ΡŽΡ‡Π²Π°, ΠΊΠΎΠ³Π°Ρ‚ΠΎ бъдС Π½Π°ΠΌΠ΅Ρ€Π΅Π½ ΠΏΡŠΡ€Π²ΠΈΡΡ‚ запис. И Π°ΠΊΠΎ Π²Π΅Ρ‡Π΅ Π΅ Π½Π°ΠΌΠ΅Ρ€Π΅Π½ Π² ΠΏΡŠΡ€Π²ΠΈΡ Π±Π»ΠΎΠΊ, вторият Π±Π»ΠΎΠΊ няма Π΄Π° бъдС изпълнСн (Π½ΠΈΠΊΠΎΠ³Π° Π½Π΅ Π΅ изпълняван с ΡƒΠ²Π°ΠΆΠ΅Π½ΠΈΠ΅ към).

β€žΠ‘ΠΊΡ€ΠΈΠ²Π°Π½Π΅ Π½Π° Ρ‚Ρ€ΡƒΠ΄Π½ΠΈ условия ΠΏΠΎΠ΄ CASEβ€œ

Π’ ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»Π½Π°Ρ‚Π° заявка ΠΈΠΌΠ° ΠΈΠ·ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»Π½ΠΎ Π½Π΅ΡƒΠ΄ΠΎΠ±Π΅Π½ ΠΌΠΎΠΌΠ΅Π½Ρ‚ - ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π½Π° ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅Ρ‚ΠΎ спрямо ΡΠ²ΡŠΡ€Π·Π°Π½Π°Ρ‚Π° Ρ‚Π°Π±Π»ΠΈΡ†Π° β€žΠ Π°Π·ΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ Π½Π° Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°β€œ. НСзависимо ΠΎΡ‚ истинността Π½Π° Π΄Ρ€ΡƒΠ³ΠΈ условия Π² ΠΈΠ·Ρ€Π°Π·Π° (Π½Π°ΠΏΡ€. Π³. β€žΠ˜Π·Ρ‚Ρ€ΠΈΡ‚β€œ НЕ Π• Π’Π―Π ΠΠž), Ρ‚Π°Π·ΠΈ Π²Ρ€ΡŠΠ·ΠΊΠ° Π²ΠΈΠ½Π°Π³ΠΈ сС изпълнява ΠΈ β€žΠΊΠΎΡΡ‚Π²Π° Ρ€Π΅ΡΡƒΡ€ΡΠΈβ€œ. ΠŸΠΎΠ²Π΅Ρ‡Π΅ ΠΈΠ»ΠΈ ΠΏΠΎ-ΠΌΠ°Π»ΠΊΠΎ ΠΎΡ‚ тях Ρ‰Π΅ Π±ΡŠΠ΄Π°Ρ‚ ΠΈΠ·Ρ€Π°Π·Ρ…ΠΎΠ΄Π²Π°Π½ΠΈ - зависи ΠΎΡ‚ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° Π½Π° Ρ‚Π°Π·ΠΈ маса.
Но ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈΡ‚Π΅ заявката, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ Ρ‚ΡŠΡ€ΡΠ΅Π½Π΅Ρ‚ΠΎ Π½Π° ΡΠ²ΡŠΡ€Π·Π°Π½ запис Π΄Π° сС ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π° само ΠΊΠΎΠ³Π°Ρ‚ΠΎ Π΅ наистина Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ:

SELECT
  ...
FROM
  "Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚" d
WHERE
  ... /*index cond*/ AND
  CASE
    WHEN "$Π§Π΅Ρ€Π½ΠΎΠ²ΠΈΠΊ" IS NULL AND "Π£Π΄Π°Π»Π΅Π½" IS NOT TRUE THEN (
      SELECT
        "БостояниС"[1] IS TRUE
      FROM
        "Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅"
      WHERE
        "@Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚" = d."@Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚"
    )
  END

Π’Π΅Π΄Π½ΡŠΠΆ ΠΎΡ‚ ΡΠ²ΡŠΡ€Π·Π°Π½Π°Ρ‚Π° маса към нас Π½ΠΈΡ‚ΠΎ Π΅Π΄Π½ΠΎ ΠΎΡ‚ ΠΏΠΎΠ»Π΅Ρ‚Π°Ρ‚Π° Π½Π΅ Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π·Π° Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚Π°, Ρ‚ΠΎΠ³Π°Π²Π° ΠΈΠΌΠ°ΠΌΠ΅ Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ Π΄Π° ΠΏΡ€Π΅Π²ΡŠΡ€Π½Π΅ΠΌ JOIN Π² условиС Π½Π° подзаявка.
НСка оставим индСксиранитС ΠΏΠΎΠ»Π΅Ρ‚Π° β€žΠΈΠ·Π²ΡŠΠ½ скобитС CASEβ€œ, Π΄ΠΎΠ±Π°Π²Π΅Ρ‚Π΅ прости условия ΠΎΡ‚ записа към Π±Π»ΠΎΠΊΠ° WHEN - ΠΈ сСга β€žΡ‚Π΅ΠΆΠΊΠ°Ρ‚Π°β€œ заявка сС изпълнява само ΠΏΡ€ΠΈ ΠΏΡ€Π΅ΠΌΠΈΠ½Π°Π²Π°Π½Π΅ към THEN.

Ѐамилията ΠΌΠΈ Π΅ "Π’ΠΎΡ‚Π°Π»"

НиС ΡΡŠΠ±ΠΈΡ€Π°ΠΌΠ΅ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π°Ρ‚Π° заявка с всички ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠΈ, описани ΠΏΠΎ-Π³ΠΎΡ€Π΅:

WITH T AS (
  SELECT
    "@Π’ΠΈΠΏΠ”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°"
  FROM
    "Π’ΠΈΠΏΠ”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°"
  WHERE
    "Π’ΠΈΠΏΠ”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°" = 'ΠŸΠ»Π°Π½Π Π°Π±ΠΎΡ‚'
)
  (
    SELECT
      TRUE
    FROM
      "Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚" d
    WHERE
      ("Π›ΠΈΡ†ΠΎ3", "Π’ΠΈΠΏΠ”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°") = (19091, (TABLE T)) AND
      CASE
        WHEN "$Π§Π΅Ρ€Π½ΠΎΠ²ΠΈΠΊ" IS NULL AND "Π£Π΄Π°Π»Π΅Π½" IS NOT TRUE THEN (
          SELECT
            "БостояниС"[1] IS TRUE
          FROM
            "Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅"
          WHERE
            "@Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚" = d."@Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚"
        )
      END
    LIMIT 1
  )
UNION ALL
  (
    SELECT
      TRUE
    FROM
      "Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚" d
    WHERE
      ("Π’ΠΈΠΏΠ”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°", "Π‘ΠΎΡ‚Ρ€ΡƒΠ΄Π½ΠΈΠΊ") = ((TABLE T), 19091) AND
      CASE
        WHEN "$Π§Π΅Ρ€Π½ΠΎΠ²ΠΈΠΊ" IS NULL AND "Π£Π΄Π°Π»Π΅Π½" IS NOT TRUE THEN (
          SELECT
            "БостояниС"[1] IS TRUE
          FROM
            "Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅"
          WHERE
            "@Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚" = d."@Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚"
        )
      END
    LIMIT 1
  )
LIMIT 1;

НастройванС [Π½Π°] индСкси

ΠžΠ±ΡƒΡ‡Π΅Π½ΠΎ ΠΎΠΊΠΎ забСляза, Ρ‡Π΅ индСксиранитС условия Π² ΠΏΠΎΠ΄Π±Π»ΠΎΠΊΠΎΠ²Π΅Ρ‚Π΅ UNION са ΠΌΠ°Π»ΠΊΠΎ ΠΏΠΎ-Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ - Ρ‚ΠΎΠ²Π° Π΅ Ρ‚Π°ΠΊΠ°, Π·Π°Ρ‰ΠΎΡ‚ΠΎ Π²Π΅Ρ‡Π΅ ΠΈΠΌΠ°ΠΌΠ΅ подходящи индСкси Π² Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π°. И Π°ΠΊΠΎ Π½Π΅ ΡΡŠΡ‰Π΅ΡΡ‚Π²ΡƒΠ²Π°Ρ…Π°, Π±ΠΈ си струвало Π΄Π° сС ΡΡŠΠ·Π΄Π°Π΄Π°Ρ‚: Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ (Person3, DocumentType) ΠΈ Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ (Ρ‚ΠΈΠΏ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚, слуТитСл).
относно Ρ€Π΅Π΄Π° Π½Π° ΠΏΠΎΠ»Π΅Ρ‚Π°Ρ‚Π° Π² условията Π½Π° ROWΠžΡ‚ Π³Π»Π΅Π΄Π½Π° Ρ‚ΠΎΡ‡ΠΊΠ° Π½Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°Π½Ρ‚Π°, Ρ€Π°Π·Π±ΠΈΡ€Π° сС, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΏΠΈΡˆΠ΅Ρ‚Π΅ (A, B) = (constA, constB)И (B, A) = (constB, constA). Но ΠΏΡ€ΠΈ запис ΠΏΠΎ Ρ€Π΅Π΄Π° Π½Π° ΠΏΠΎΠ»Π΅Ρ‚Π°Ρ‚Π° Π² индСкса, Ρ‚Π°ΠΊΠ°Π²Π° заявка Π΅ просто ΠΏΠΎ-ΡƒΠ΄ΠΎΠ±Π½Π° Π·Π° отстраняванС Π½Π° Π³Ρ€Π΅ΡˆΠΊΠΈ ΠΏΠΎ-късно.
Какво има в плана?
PostgreSQL Antipatterns: Π²Ρ€Π΅Π΄Π½ΠΈ JOIN ΠΈ OR
[Π²ΠΈΠΆΡ‚Π΅ expand.tensor.ru]

Π—Π° съТалСниС нямахмС ΠΊΡŠΡΠΌΠ΅Ρ‚ ΠΈ Π½ΠΈΡ‰ΠΎ Π½Π΅ бСшС Π½Π°ΠΌΠ΅Ρ€Π΅Π½ΠΎ Π² ΠΏΡŠΡ€Π²ΠΈΡ Π±Π»ΠΎΠΊ UNION, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ вторият всС ΠΎΡ‰Π΅ бСшС изпълнСн. Но Π΄ΠΎΡ€ΠΈ ΠΈ Ρ‚Π°ΠΊΠ° – само 0.037ms ΠΈ 11 Π±ΡƒΡ„Π΅Ρ€Π°!
УскорихмС заявката ΠΈ Π½Π°ΠΌΠ°Π»ΠΈΡ…ΠΌΠ΅ ΠΈΠ·ΠΏΠΎΠΌΠΏΠ²Π°Π½Π΅Ρ‚ΠΎ Π½Π° Π΄Π°Π½Π½ΠΈ Π² ΠΏΠ°ΠΌΠ΅Ρ‚Ρ‚Π° няколко хиляди ΠΏΡŠΡ‚ΠΈ, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ доста прости Ρ‚Π΅Ρ…Π½ΠΈΠΊΠΈ - Π΄ΠΎΠ±ΡŠΡ€ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ с ΠΌΠ°Π»ΠΊΠΎ ΠΊΠΎΠΏΠΈ-пСйст. πŸ™‚

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

ДобавянС Π½Π° Π½ΠΎΠ² ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€