Skip to content
This repository was archived by the owner on Jul 1, 2025. It is now read-only.
/ imdb-db Public archive

PostgreSQL JSONB performance analysis using IMDB dataset. Includes data parsing from actors.list.txt, JSONB query examples, access time measurements across the 2KB TOAST threshold, and update impact analysis. Demonstrates the performance characteristics of PostgreSQL's JSONB storage with visualizations and detailed findings.

Notifications You must be signed in to change notification settings

seigtm/imdb-db

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

ΠŸΠΎΡΡ‚Π°Π½ΠΎΠ²ΠΊΠ° Π·Π°Π΄Π°Ρ‡ΠΈ

PostgreSQL стала ΠΏΠ΅Ρ€Π²ΠΎΠΉ рСляционной Π±Π°Π·ΠΎΠΉ Π΄Π°Π½Π½Ρ‹Ρ…, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‰Π΅ΠΉ слабоструктурированныС Π΄Π°Π½Π½Ρ‹Π΅. Π’ PostgreSQL для этого ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ JSON (JavaScript Object Notation, Π—Π°ΠΏΠΈΡΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° JavaScript RFC 7159), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΠΌΠ΅Π΅Ρ‚ Π΄Π²Π° прСдставлСния: json ΠΈ jsonb. Для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ эффСктивного ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° запросов ΠΊ этим Ρ‚ΠΈΠΏΠ°ΠΌ Π΄Π°Π½Π½Ρ‹Ρ… Π² Postgres Ρ‚Π°ΠΊΠΆΠ΅ имССтся Ρ‚ΠΈΠΏ jsonpath. ΠžΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½ΠΎ JSON появился Π² PostgreSQL Π² 2014 Π³ΠΎΠ΄Ρƒ. PostgreSQL с JSONB совмСщаСт Π³ΠΈΠ±ΠΊΠΎΡΡ‚ΡŒ NoSQL, Π° Ρ‚Π°ΠΊΠΆΠ΅ Π½Π°Π΄Ρ‘ΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΈ богатство Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ рСляционных Π‘Π£Π‘Π”.

ΠŸΡ€Π°ΠΊΡ‚ΠΈΡ‡Π΅ΡΠΊΠ°Ρ Ρ‡Π°ΡΡ‚ΡŒ

Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ PostgreSQL Π±Π°Π·Ρƒ Π΄Π°Π½Π½Ρ‹Ρ… imdb, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΡƒΡŽ стандартныС Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ ΠΈ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ jsonb. Для Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΎΠ΄ΠΈΠ½ Ρ„Π°ΠΉΠ» actors.list.txt ΠΈΠ· ΠΏΠ°ΠΏΠΊΠΈ DataSet.

ОписаниС Ρ„Π°ΠΉΠ»Π°

  1. Кодовая страница - ISO 8859-1.

  2. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚Π΅Π»ΠΈ: HT (0x09) - horizontal_tab, LF (0x0A) - line_feed.

    Для ΠΏΠΎΠ»Π΅ΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΎΠ΄ΠΈΠ½ ΠΈΠ»ΠΈ нСсколько Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚Π΅Π»Π΅ΠΉ HT, для Ρ€ΠΎΠ»Π΅ΠΉ Π°ΠΊΡ‚Π΅Ρ€Π° ΠΎΠ΄ΠΈΠ½ LF, для Π°ΠΊΡ‚Π΅Ρ€ΠΎΠ² Π΄Π²Π° LF.

  3. ΠŸΡ€Π°Π²ΠΈΠ»Π° синтаксичСского Ρ€Π°Π·Π±ΠΎΡ€Π° поля Titles:

    1. ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ title ΠΈΠ»ΠΈ "title" = Π½Π°Π·Π²Π°Π½ΠΈΠ΅ Ρ€ΠΎΠ»ΠΈ, пСрСносим Π² json с ΠΎΠ΄ΠΈΠ½Π°Ρ€Π½Ρ‹ΠΌΠΈ ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠ°ΠΌΠΈ ΠΈΠ»ΠΈ Π±Π΅Π· ΠΊΠ°Π²Ρ‹Ρ‡Π΅ΠΊ;

    2. Π²Ρ‚ΠΎΡ€ΠΎΠΉ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ (year) = Π³ΠΎΠ΄ Ρ€ΠΎΠ»ΠΈ, ΠΏΠ΅Ρ€Π²Ρ‹Π΅ ΠΊΡ€ΡƒΠ³Π»Ρ‹Π΅ скобки, ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ (????) - Π΄Π°Ρ‚Π° нСизвСстна;

    3. Ρ‚Ρ€Π΅Ρ‚ΠΈΠΉ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚/Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ (type1) = Ρ‚ΠΈΠΏ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Π°, всС Ρ‡Ρ‚ΠΎ послС Π³ΠΎΠ΄Π° Π² ΠΊΡ€ΡƒΠ³Π»Ρ‹Ρ… скобках:

      • (V) - Π²ΠΈΠ΄Π΅ΠΎ ΠΈΠ»ΠΈ ΠΊΠ»ΠΈΠΏ;
      • (TV) - для тСлСвидСния;
      • (VG) - для Π²ΠΈΠ΄Π΅ΠΎ ΠΈΠ³Ρ€Ρ‹;
      • (archive footage) - Π°Ρ€Ρ…ΠΈΠ²Π½Ρ‹Π΅ ΠΈΠ»ΠΈ Ρ€Π°Π½Π½ΠΈΠ΅ ΠΊΠ°Π΄Ρ€Ρ‹;
      • (uncredited) – Π½Π΅ зарСгистрирован ΠΈΠ»ΠΈ Π½Π΅ ΡƒΠΊΠ°Π·Π°Π½ Π² Ρ‚ΠΈΡ‚Ρ€Π°Ρ…;
      • (voice) - ΠΎΠ·Π²ΡƒΡ‡ΠΊΠ° ΠΈΠ»ΠΈ Π·Π°ΠΊΠ°Π΄Ρ€ΠΎΠ²Ρ‹ΠΉ голос.

      ΠœΠΎΠΆΠ΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ нСсколько Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ² ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ, Ρ‚ΠΎΠ³Π΄Π° слСдуСт ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ»ΡŽΡ‡ΠΈ ΠΊΠ°ΠΊ type1, type2, type3, Ρ‚.ΠΊ. Π² jsonb всС ΠΊΠ»ΡŽΡ‡ΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ;

    4. Ρ‡Π΅Ρ‚Π²Π΅Ρ€Ρ‚Ρ‹ΠΉ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚/Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ {series name} = Π½Π°Π·Π²Π°Π½ΠΈΠ΅ сСрии Π² сСриалС: Π² Ρ„ΠΈΠ³ΡƒΡ€Π½Ρ‹Ρ… скобках, #xx.yy = Π½ΠΎΠΌΠ΅Ρ€_сСзона/Π½ΠΎΠΌΠ΅Ρ€_сСрии;

    5. пятый Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚/Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ (as character) = пояснСниС ΠΈΠΌΠ΅Π½ΠΈ гСроя: находится Π² скобках ΠΏΠ΅Ρ€Π΅Π΄ ΠΈΠΌΠ΅Π½Π΅ΠΌ гСроя, добавляСм Π² json ΠΊ ΠΊΠ»ΡŽΡ‡Ρƒ "character name" Π² ΠΊΠΎΠ½Ρ†Π΅ ΠΊΠ°ΠΊ Π΅ΡΡ‚ΡŒ Π² скобках;

    6. ΡˆΠ΅ΡΡ‚ΠΎΠΉ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚/Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ [character name] = имя гСроя: Π² ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚Π½Ρ‹Ρ… скобках;

    7. сСдьмой Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚/Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ <credit> = Π½ΠΎΠΌΠ΅Ρ€ Π² Ρ‚ΠΈΡ‚Ρ€Π°Ρ…: Π² Ρ‚Ρ€Π΅ΡƒΠ³ΠΎΠ»ΡŒΠ½Ρ‹Ρ… скобках.

Π˜ΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΈΠ· ΠΏΡ€Π°Π²ΠΈΠ» ΠΏΡ€ΠΈ Ρ€Π°Π·Π±ΠΎΡ€Π΅

Π Π΅Π°Π»ΡŒΠ½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ Π½Π΅ΠΈΠ΄Π΅Π°Π»ΡŒΠ½Ρ‹, Ρ„Π°ΠΉΠ» с Π°ΠΊΡ‚Π΅Ρ€Π°ΠΌΠΈ Ρ‚ΠΎΠΆΠ΅, Ρ‚.ΠΎ. Π΅ΡΡ‚ΡŒ строки, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ΡΡ Π΄ΠΈΠ°Π³Ρ€Π°ΠΌΠΌΠΎΠΉ Ρ€Π°Π·Π±ΠΎΡ€Π°. Π­Ρ‚ΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΡ‡Π΅ΡΡ‚ΡŒ.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ:

  1. Π’Π½ΡƒΡ‚Ρ€ΠΈ Ρ€ΠΎΠ»ΠΈ Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚Π΅Π»ΠΈ ΠΏΡ€ΠΎΠ±Π΅Π»Ρ‹.
  2. Для поля name ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ имя - оставляСм Ρ„Π°ΠΌΠΈΠ»ΠΈΡŽ пустой.
  3. ИмСна, Ρ„Π°ΠΌΠΈΠ»ΠΈΠΈ Π²ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‚ скобки ΠΈ Ρ€Π°Π·Π½Ρ‹Π΅ странныС символы - отставляСм ΠΊΠ°ΠΊ Π΅ΡΡ‚ΡŒ.
  4. ПолС (as character) ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΡΡ‚ΡŒΡΡ ΠΊΠ°ΠΊ (also as character) - ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠ»ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π΅Ρ‰Π΅ type.
  5. (2014/III) - Π·Π°ΠΌΠ΅Π½Π° Π½Π° (2014).
  6. (????) - Π·Π°ΠΌΠ΅Π½Π° Π½Π° (0000).
  7. (????/III) Π·Π°ΠΌΠ΅Π½Π° Π½Π° (0000).

Поля Π‘Π£Π‘Π”

  • id integer (PRIMARY KEY гСнСрируСтся ΠΈΠ· ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ).
  • ActorFirstName varchar (ΠΈΠ· поля Name, исходный Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ SecondName, FirstName).
  • ActorSecondName varchar (ΠΈΠ· поля Name, исходный Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ SecondName, FirstName).
  • RolesName jsonb (ΠΈΠ· поля Titles ΠΏΠΎ ΠΏΡ€Π°Π²ΠΈΠ»Ρƒ Ρ€Π°Π·Π±ΠΎΡ€Π°).

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ записи Π² Ρ„Π°ΠΉΠ»Π΅

Freeman, Morgan (I) 10 Items or Less (2006)  [Him]  <1>
   100 Years at the Movies (1994) (TV)  (archive footage)  [Himself]
   11th Annual Screen Actors Guild Awards (2005) (TV)  [Himself - Winner & Nominee]
   12th Annual Screen Actors Guild Awards (2006) (TV)  [Himself]
   15th Annual Critics' Choice Movie Awards (2010) (TV)  [Himself]
   16th Annual Screen Actors Guild Awards (2010) (TV)  [Himself]
   17th Annual Screen Actors Guild Awards (2011) (TV)  [Himself - Presenter: Life Achievement Award]
   1995 VH1 Honors (1995) (TV)  [Himself]
   1996 Blockbuster Entertainment Awards (1996) (TV)  [Himself]
   19th Annual Screen Actors Guild Awards (2013) (TV)  [Himself - Presenter]  <52>
   2003 World Awards (2003) (TV)  [Himself]
   2014 Primetime Creative Arts Emmy Awards (2014) (TV)  [Himself - Presenter: Outstanding Guest Actress in a Comedy Series]  <178>
   2016 Creative Arts Emmys (2016) (TV)  [Himself - Presenter: Outstanding Special Class Program and Nominated: Outstanding Informational Series or Special]  <148>
   20th Annual Screen Actors Guild Awards (2014) (TV)  (uncredited)  [Himself - Presenter]
   22nd NAACP Image Awards (1990) (TV)  [Himself]
   24 Hours of Reality and Live Earth: The World Is Watching (2015) (TV)  [Himself]
   25th NAACP Image Awards (1993) (TV)  [Himself]
   29th NAACP Image Awards (1998) (TV)  [Himself]
   30th NAACP Image Awards (1999) (TV)  [Himself]
   3rd Annual Screen Actors Guild Awards (1997) (TV)  [Himself]
   41st NAACP Image Awards (2010) (TV)  [Himself]
   5 Flights Up (2014)  [Alex Carver]  <2>
   73rd Golden Globe Awards (2016) (TV)  [Himself - Presenter: Director-Motion Picture]  <134>
   A Cautionary Tale: The Making of 'The Sum of All Fears' (2002) (V)  [Himself]
   A Century of Cinema (1994)  [Himself]

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ шаблона Ρ„Π°ΠΉΠ»Π°

Π”Π²Π΅ ΠΏΠ΅Ρ€Π²Ρ‹Π΅ строки Π² Ρ„Π°ΠΉΠ»Π΅ ΠΏΡ€ΠΎΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ ΠΏΡ€ΠΈ Ρ€Π°Π·Π±ΠΎΡ€Π΅, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ½ΠΈ содСрТат Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ списка Ρ€ΠΎΠ»Π΅ΠΉ:

Name                    Titles 
----                    ------

Π”Π°Π»Π΅Π΅ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ Ρ„Π°ΠΉΠ»Π° выглядит ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

SecondName, FirstName HT HT HT title (year)                                [character name] <credit> LF
                      HT HT HT title (year)                (type1)         [character name]          LF
LF
SecondName, FirstName       HT title (year)                                [character name] <credit> LF
                      HT HT HT title (year) {series name}  (type1) (type2) [character name] <credit> LF
                      HT HT HT title (year) (as character)                 [character name]          LF

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Ρ€Π°Π·Π±ΠΎΡ€Π° для Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹

  • id *****

  • ActorFirstName "Morgan"

  • ActorSecondName "Freeman"

  • RolesName

    {
        "roles": [
            {
                "title": "The Shawshank Redemption",
                "year": "1994",
                "character name": "Ellis Boyd 'Red' Redding",
                "credit": "2"
            },
            {
                "title": "The True Story of Glory Continues",
                "year": "1991",
                "type1": "voice",
                "character name": "Narrator",
                "credit": "1"
            },
            {
                "title": "Unforgiven",
                "year": "1992",
                "character name": "Ned Logan",
                "credit": "1"
            },
            {
                "title": "Through the Wormhole",
                "year": "2010",
                "series name": "Are Aliens Inside Us? (#6.5)",
                "character name": "Himself - Narrator",
                "credit": "1"
            }
        ]
    }

Π—Π°Π΄Π°Ρ‡ΠΈ

  1. Π‘ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ 4-5 запросов с использованиСм api postgresql для jsonb:
    • ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π½Π° Π²Ρ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ ΠΈ сущСствованиС jsonb;
    • ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΏΠΎ индСксу ΠΊ элСмСнтам jsonb;
    • ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ язык jsonpath;
    • ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ для Ρ‚ΠΈΠΏΠ° jsonb.
  2. Π˜Π·ΠΌΠ΅Ρ€ΠΈΡ‚ΡŒ врСмя доступа ΠΊ полю jsonb для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ строчки (Π² Π²ΠΈΠ΄Π΅ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ ΠΈΠ»ΠΈ Π³Ρ€Π°Ρ„ΠΈΠΊΠ°). ΠžΡ†Π΅Π½ΠΈΡ‚ΡŒ влияниС Π΄Π»ΠΈΠ½Ρ‹ строки Π½Π° ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ доступа (оТидаСтся ΡΡ‚ΡƒΠΏΠ΅Π½ΡŒΠΊΠ° Π΄ΠΎ 2kB, послС линСйная Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ). Для этого слСдуСт ΠΈΠ·ΠΌΠ΅Ρ€ΠΈΡ‚ΡŒ врСмя чтСния year ΠΏΠ΅Ρ€Π²ΠΎΠΉ Ρ€ΠΎΠ»ΠΈ Π°ΠΊΡ‚Π΅Ρ€Π° (explain analyze). Для точности ΠΎΡ†Π΅Π½ΠΊΠΈ Π²Π°ΠΆΠ½ΠΎ ΡƒΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒ Ρ…Ρ€Π°Π½ΠΈΠΌΡƒΡŽ Π΄Π»ΠΈΠ½Ρƒ (jsonb хранится Π² сТатой Ρ„ΠΎΡ€ΠΌΠ΅). Как ΠΌΠΎΠΆΠ½ΠΎ это влияниС ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΡ‚ΡŒ?
  3. Π‘ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ запрос Π½Π° ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ year Ρƒ ΠΏΠ΅Ρ€Π²ΠΎΠΉ Ρ€ΠΎΠ»ΠΈ Π°ΠΊΡ‚Π΅Ρ€Π°. Π‘Ρ€Π°Π²Π½ΠΈΡ‚ΡŒ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ объСма Π‘Π” для Π°ΠΊΡ‚Π΅Ρ€Π° с ΠΌΠ°Π»Ρ‹ΠΌ ΠΊΠΎΠ»-Π²ΠΎΠΌ Ρ€ΠΎΠ»Π΅ΠΉ ΠΈ Π°ΠΊΡ‚Π΅Ρ€Π° с большим количСством Ρ€ΠΎΠ»Π΅ΠΉ (toasted roles).

ΠžΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹

  1. Π Π°Π·Π±ΠΎΡ€ исходного тСкста ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚ΡŒ ΠΊΠ°ΠΊ с использованиСм Ρ…Ρ€Π°Π½ΠΈΠΌΠΎΠΉ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹ plpython3u, Ρ‚Π°ΠΊ ΠΈ Π»ΡŽΠ±Ρ‹ΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, python, C#, java…). Для Ρ…Ρ€Π°Π½ΠΈΠΌΠΎΠΉ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹ Π΅ΡΡ‚ΡŒ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ Π½Π° объСм тСкста для вставки.
  2. НС прСдполагаСтся использованиС ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΎΡ‡Π½ΠΎΠ³ΠΎ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° Ρ„Π°ΠΉΠ»Π° ΠΏΡ€ΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ΅ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, csv).
  3. Для построСния Π³Ρ€Π°Ρ„ΠΈΠΊΠ° ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π½Π΅ всС Π΄Π°Π½Π½Ρ‹Π΅, Π½ΠΎ Π²Ρ‹Π±ΠΎΡ€ΠΊΠ° Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, 50 для Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠΉ ΡΡ‚ΡƒΠΏΠ΅Π½ΡŒΠΊΠΈ ΠΈ 50 для Π»ΠΈΠ½Π΅ΠΉΠ½ΠΎΠΉ части).
  4. ΠŸΡ€ΠΈ построСнии Π³Ρ€Π°Ρ„ΠΈΠΊΠ° слСдуСт Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠ²Π°Ρ‚ΡŒ случайныС выбросы (ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Π½Π° сСрвСр), ΠΆΠ΅Π»Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚ΡŒ усрСднСниС ΠΏΠΎ значСниям Π³Ρ€Π°Ρ„ΠΈΠΊΠ°.

Π’Π΅ΠΌΡ‹ для ΠΏΡ€ΠΎΡ€Π°Π±ΠΎΡ‚ΠΊΠΈ

ΠžΡ‚Π²Π΅Ρ‚Ρ‹ Π½Π° вопросы ΠΏΠΎ PostgreSQL ΠΈ JSON

Π’ Ρ‡Π΅ΠΌ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ Ρ‚ΠΈΠΏΠΎΠ² json ΠΈ jsonb?

PostgreSQL ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Π΄Π²Π° Ρ‚ΠΈΠΏΠ° для хранСния JSON-Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ сущСствСнно Ρ€Π°Π·Π»ΠΈΡ‡Π°ΡŽΡ‚ΡΡ ΠΏΠΎ своСй Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ:

  1. Π€ΠΎΡ€ΠΌΠ°Ρ‚ хранСния:

    • json Ρ…Ρ€Π°Π½ΠΈΡ‚ Ρ‚ΠΎΡ‡Π½ΡƒΡŽ Ρ‚Π΅ΠΊΡΡ‚ΠΎΠ²ΡƒΡŽ копию Π²Π²Π΅Π΄Π΅Π½Π½ΠΎΠ³ΠΎ JSON ΠΊΠ°ΠΊ Π΅ΡΡ‚ΡŒ, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ всС ΠΏΡ€ΠΎΠ±Π΅Π»Ρ‹, Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΈ порядок ΠΊΠ»ΡŽΡ‡Π΅ΠΉ;
    • jsonb Ρ…Ρ€Π°Π½ΠΈΡ‚ Π΄Π°Π½Π½Ρ‹Π΅ Π² Π±ΠΈΠ½Π°Ρ€Π½ΠΎΠΌ Π΄Π΅ΠΊΠΎΠΌΠΏΠΎΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΌ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅, Ρ‡Ρ‚ΠΎ позволяСт быстро ΠΎΠ±Ρ€Π°Ρ‰Π°Ρ‚ΡŒΡΡ ΠΊ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΌ элСмСнтам.
  2. Π­Ρ„Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎΡΡ‚ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ:

    • json Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠ³ΠΎ парсинга ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ запросС, Ρ‡Ρ‚ΠΎ сниТаСт ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ;
    • jsonb хранится ΡƒΠΆΠ΅ Π² ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Π½Π½ΠΎΠΌ Π²ΠΈΠ΄Π΅, Ρ‡Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ всС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ поиска ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ быстрСС.
  3. ΠŸΠΎΡ€ΡΠ΄ΠΎΠΊ ΠΊΠ»ΡŽΡ‡Π΅ΠΉ:

    • json сохраняСт порядок ΠΊΠ»ΡŽΡ‡Π΅ΠΉ Π² Ρ‚ΠΎΠΌ Π²ΠΈΠ΄Π΅, Π² ΠΊΠ°ΠΊΠΎΠΌ ΠΎΠ½ΠΈ Π±Ρ‹Π»ΠΈ Π²Π²Π΅Π΄Π΅Π½Ρ‹;
    • jsonb Π½Π΅ сохраняСт порядок ΠΊΠ»ΡŽΡ‡Π΅ΠΉ (ΠΎΠ½ΠΈ ΡΠΎΡ€Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ΡΡ автоматичСски для ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ доступа).
  4. Π˜Π½Π΄Π΅ΠΊΡΠ°Ρ†ΠΈΡ:

    • json Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΈΠ½Π΄Π΅ΠΊΡΠ°Ρ†ΠΈΡŽ, Ρ‡Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ поиск ΠΏΠΎ содСрТимому нСэффСктивным;
    • jsonb ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ спСциализированныС GIN-индСксы, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠ΅ быстро ΠΈΠ·Π²Π»Π΅ΠΊΠ°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎ ΠΊΠ»ΡŽΡ‡Π°ΠΌ ΠΈ значСниям.
  5. Π”ΡƒΠ±Π»ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ΡΡ ΠΊΠ»ΡŽΡ‡ΠΈ:

    • json сохраняСт всС Π΄ΡƒΠ±Π»ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ΡΡ ΠΊΠ»ΡŽΡ‡ΠΈ ΠΊΠ°ΠΊ Π΅ΡΡ‚ΡŒ;
    • jsonb сохраняСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ послСднСС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π΄ΡƒΠ±Π»ΠΈΡ€ΡƒΡŽΡ‰Π΅Π³ΠΎΡΡ ΠΊΠ»ΡŽΡ‡Π°.

Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, json ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ для случаСв, ΠΊΠΎΠ³Π΄Π° трСбуСтся Ρ‚ΠΎΡ‡Π½ΠΎΠ΅ сохранСниС исходного Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π°, Π° jsonb - ΠΊΠΎΠ³Π΄Π° Π²Π°ΠΆΠ½Ρ‹ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ запросов ΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ эффСктивного поиска.

КакиС Ρ‚ΠΈΠΏΡ‹ индСксации ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ jsonb?

JSONB ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ нСсколько Ρ‚ΠΈΠΏΠΎΠ² индСксации, Ρ‡Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ Π΅Π³ΠΎ ΠΌΠΎΡ‰Π½Ρ‹ΠΌ инструмСнтом для Ρ€Π°Π±ΠΎΡ‚Ρ‹ со слабоструктурированными Π΄Π°Π½Π½Ρ‹ΠΌΠΈ:

  1. GIN (Generalized Inverted Index) - Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ эффСктивный Ρ‚ΠΈΠΏ индСксации для JSONB с двумя Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π°ΠΌΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ²:

    • jsonb_ops (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ) - индСксируСт ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΊΠ»ΡŽΡ‡ ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ @>, ?, ?&, ?|;
    • jsonb_path_ops - ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ для ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ (@>), Π±ΠΎΠ»Π΅Π΅ ΠΊΠΎΠΌΠΏΠ°ΠΊΡ‚Π΅Π½ ΠΈ быстрСС для Ρ‚Π°ΠΊΠΈΡ… запросов:
    CREATE INDEX idx_actors_roles ON actors USING GIN (RolesName jsonb_path_ops);
  2. B-tree индСксы - ΠΌΠΎΠ³ΡƒΡ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ для сравнСния JSONB-ΠΏΠΎΠ»Π΅ΠΉ Ρ†Π΅Π»ΠΈΠΊΠΎΠΌ:

    CREATE INDEX idx_json_equality ON actors (RolesName);
  3. Π€ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Π΅ индСксы - для индСксации Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹Ρ… ΠΊΠ»ΡŽΡ‡Π΅ΠΉ:

    CREATE INDEX idx_year ON actors ((RolesName->'roles'->0->>'year'));
  4. ЧастичныС индСксы - для индСксирования Ρ‚ΠΎΠ»ΡŒΠΊΠΎ строк, ΡƒΠ΄ΠΎΠ²Π»Π΅Ρ‚Π²ΠΎΡ€ΡΡŽΡ‰ΠΈΡ… ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΌΡƒ ΡƒΡΠ»ΠΎΠ²ΠΈΡŽ:

    CREATE INDEX idx_actors_with_type ON actors USING GIN (RolesName)
    WHERE jsonb_path_exists(RolesName, '$.roles[*].type1');
  5. ΠšΠΎΠΌΠ±ΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ индСксы - для ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ индСксации Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΏΠΎΠ»Π΅ΠΉ:

    CREATE INDEX idx_actors_combined ON actors (ActorFirstName, ActorSecondName, (RolesName->'roles'->0->>'year'));

ΠŸΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ Π²Ρ‹Π±ΠΎΡ€ Ρ‚ΠΈΠΏΠ° индСкса сущСствСнно влияСт Π½Π° ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ запросов ΠΊ JSONB-Π΄Π°Π½Π½Ρ‹ΠΌ.

Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ jsonpath?

JSONPath - это спСциализированный язык запросов для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с JSON-Π΄Π°Π½Π½Ρ‹ΠΌΠΈ, Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π½Ρ‹ΠΉ Π² PostgreSQL 12 ΠΈ стандартизированный Π² SQL/JSON:

  1. Бинтаксис ΠΈ основныС элСмСнты:

    • $ - ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠΉ элСмСнт JSON-Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°;
    • .key ΠΈΠ»ΠΈ ."key with spaces" - доступ ΠΊ полю ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°;
    • [*] - ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΊΠΎ всСм элСмСнтам массива;
    • ?() - Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ для Π²Ρ‹Π±ΠΎΡ€ΠΊΠΈ элСмСнтов;
    • @ - ссылка Π½Π° Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌΡ‹ΠΉ элСмСнт.
  2. ВозмоТности языка:

    • БлоТная навигация ΠΏΠΎ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΌ структурам;
    • АрифмСтичСскиС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ с ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌΡ‹ΠΌΠΈ числовыми значСниями;
    • ЛогичСскиС ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ (&&, ||, !);
    • ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ сравнСния (==, !=, <, <=, >, >=);
    • Поиск ΠΏΠΎ ΡˆΠ°Π±Π»ΠΎΠ½Ρƒ с использованиСм рСгулярных Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ (like_regex).
  3. ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с jsonpath:

    • jsonb_path_exists(json, path) - провСряСт, ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ Π»ΠΈ элСмСнты, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ ΠΏΡƒΡ‚ΠΈ;
    • jsonb_path_query(json, path) - ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅Ρ‚ всС значСния, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ ΠΏΡƒΡ‚ΠΈ;
    • jsonb_path_query_array(json, path) - Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ Π² Π²ΠΈΠ΄Π΅ JSON-массива;
    • jsonb_path_query_first(json, path) - Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ элСмСнт.
  4. ΠŸΡ€ΠΈΠΌΠ΅Ρ€ использования:

    SELECT ActorFirstName, ActorSecondName
    FROM actors
    WHERE jsonb_path_exists(
        RolesName,
        '$.roles[*] ? (@.year >= "2010" && @.credit == "1")'
    );

    Π­Ρ‚ΠΎΡ‚ запрос Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ Π°ΠΊΡ‚Π΅Ρ€ΠΎΠ², ΡΡ‹Π³Ρ€Π°Π²ΡˆΠΈΡ… Π³Π»Π°Π²Π½ΡƒΡŽ Ρ€ΠΎΠ»ΡŒ Π² Ρ„ΠΈΠ»ΡŒΠΌΠ°Ρ… 2010 Π³ΠΎΠ΄Π° ΠΈ ΠΏΠΎΠ·ΠΆΠ΅.

JSONPath прСдоставляСт Π±ΠΎΠ»Π΅Π΅ ΠΌΠΎΡ‰Π½Ρ‹ΠΉ ΠΈ Π΄Π΅ΠΊΠ»Π°Ρ€Π°Ρ‚ΠΈΠ²Π½Ρ‹ΠΉ способ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с JSON-Π΄Π°Π½Π½Ρ‹ΠΌΠΈ ΠΏΠΎ ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ со стандартными ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π°ΠΌΠΈ доступа ΠΊ полям (->, ->>) ΠΈ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΡƒΠΏΡ€ΠΎΡ‰Π°Π΅Ρ‚ слоТныС запросы ΠΊ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΌ структурам.

Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ toasted object?

TOAST (The Oversized-Attribute Storage Technique) - это ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ PostgreSQL для эффСктивного хранСния ΠΈ доступа ΠΊ большим значСниям Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ²:

  1. ΠŸΡ€ΠΈΠ½Ρ†ΠΈΠΏ Ρ€Π°Π±ΠΎΡ‚Ρ‹:

    • PostgreSQL Ρ…Ρ€Π°Π½ΠΈΡ‚ строки Π² страницах фиксированного Ρ€Π°Π·ΠΌΠ΅Ρ€Π° (ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ 8 KB);
    • Когда Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π° слишком Π²Π΅Π»ΠΈΠΊΠΎ (ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ°Π΅Ρ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΉ ΠΏΠΎΡ€ΠΎΠ³), ΠΎΠ½ΠΎ "тостируСтся" - пСрСмСщаСтся Π²ΠΎ внСшнюю TOAST-Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ;
    • Π’ основной Ρ‚Π°Π±Π»ΠΈΡ†Π΅ остаСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ нСбольшой ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° TOAST-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅.
  2. ΠŸΠΎΡ€ΠΎΠ³ΠΎΠ²Ρ‹Π΅ значСния:

    • Для JSONB ΠΏΠΎΡ€ΠΎΠ³ TOAST составляСт ΠΎΠΊΠΎΠ»ΠΎ 2 KB;
    • Π”Π°Π½Π½Ρ‹Π΅, ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ°ΡŽΡ‰ΠΈΠ΅ этот ΠΏΠΎΡ€ΠΎΠ³, автоматичСски ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ Π² TOAST-Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹.
  3. Π‘Ρ‚Ρ€Π°Ρ‚Π΅Π³ΠΈΠΈ хранСния TOAST-Π΄Π°Π½Π½Ρ‹Ρ…:

    Π’ стратСгиях ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Π΄Π²Π° ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Ρ… ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ°:

    • Π‘ΠΆΠ°Ρ‚ΠΈΠ΅ - процСсс ΡƒΠΌΠ΅Π½ΡŒΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° Π΄Π°Π½Π½Ρ‹Ρ… с ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ° LZ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ PostgreSQL ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ для TOAST-Π΄Π°Π½Π½Ρ‹Ρ…. Π‘ΠΆΠ°Ρ‚ΠΈΠ΅ позволяСт сущСствСнно ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΡ‚ΡŒ Π·Π°Π½ΠΈΠΌΠ°Π΅ΠΌΠΎΠ΅ пространство, особСнно для тСкстовых Π΄Π°Π½Π½Ρ‹Ρ…, Π½ΠΎ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Π²Ρ‹Ρ‡ΠΈΡΠ»ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… рСсурсов ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ чтСния ΠΈ записи.
    • Π’Π½Π΅ΡˆΠ½Π΅Π΅ Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ - ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ пСрСмСщСния Π±ΠΎΠ»ΡŒΡˆΠΈΡ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ ΠΈΠ· основной Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ Π²ΠΎ Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½ΡƒΡŽ TOAST-Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ. ΠŸΡ€ΠΈ этом Π² основной строкС Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ остаСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ нСбольшой ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ (16 Π±Π°ΠΉΡ‚), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ссылаСтся Π½Π° ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΡƒΡŽ запись Π² TOAST-Ρ‚Π°Π±Π»ΠΈΡ†Π΅. Π­Ρ‚ΠΎ позволяСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ эффСктивноС Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ Π±ΠΎΠ»ΡŒΡˆΠΈΡ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², Π½ΠΎ добавляСт Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΊ диску ΠΏΡ€ΠΈ доступС ΠΊ Π΄Π°Π½Π½Ρ‹ΠΌ.

    Π‘Π°ΠΌΠΈ стратСгии ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚, ΠΊΠ°ΠΊΠΈΠ΅ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΡ‹ Π±ΡƒΠ΄ΡƒΡ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ для TOAST-Π΄Π°Π½Π½Ρ‹Ρ…:

    • PLAIN - ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΊΠ°ΠΊ сТатиС, Ρ‚Π°ΠΊ ΠΈ внСшнСС Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅. Π­Ρ‚ΠΎ СдинствСнная возмоТная стратСгия для столбцов с Ρ‚ΠΈΠΏΠ°ΠΌΠΈ Π΄Π°Π½Π½Ρ‹Ρ…, Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‰ΠΈΠΌΠΈ TOAST;
    • EXTENDED - позволяСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ сТатиС, Ρ‚Π°ΠΊ ΠΈ внСшнСС Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ для Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π° TOAST-ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² Π΄Π°Π½Π½Ρ‹Ρ…). Π‘Π½Π°Ρ‡Π°Π»Π° прСдпринимаСтся ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ° сТатия, Π° Π·Π°Ρ‚Π΅ΠΌ, Ссли строка всС Π΅Ρ‰Π΅ слишком большая, примСняСтся внСшнСС Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅;
    • EXTERNAL - Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ внСшнСС Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅, Π½ΠΎ Π½Π΅ сТатиС. ИспользованиС EXTERNAL Π΄Π΅Π»Π°Π΅Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ с подстроками Π½Π° ΡˆΠΈΡ€ΠΎΠΊΠΈΡ… тСкстовых ΠΈ bytea столбцах быстрСС (Π·Π° счСт увСличСния Π·Π°Π½ΠΈΠΌΠ°Π΅ΠΌΠΎΠ³ΠΎ пространства), ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ эти ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ для извлСчСния Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Ρ… частСй внСшнСго значСния, ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ΠΎ Π½Π΅ сТато;
    • MAIN - Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ сТатиС, Π½ΠΎ Π½Π΅ внСшнСС Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅. (ЀактичСски, внСшнСС Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ всё Ρ€Π°Π²Π½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ для Ρ‚Π°ΠΊΠΈΡ… столбцов, Π½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊΠ°ΠΊ послСднСС срСдство, ΠΊΠΎΠ³Π΄Π° Π½Π΅Ρ‚ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ способа ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΡ‚ΡŒ строку Π΄ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€Π°, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰Π΅Π³ΠΎ Ρ€Π°Π·ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ Π΅Ρ‘ Π½Π° страницС).
  4. ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с TOAST-ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ:

    • Π’Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ часто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Ρ… Π½Π΅Π±ΠΎΠ»ΡŒΡˆΠΈΡ… ΠΏΠΎΠ»Π΅ΠΉ Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ столбцы;
    • ИспользованиС частичных индСксов для ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ доступа;
    • Π Π°Π·Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π±ΠΎΠ»ΡŒΡˆΠΈΡ… JSON-Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² Π½Π° логичСскиС части.

TOAST - это ΠΏΡ€ΠΎΠ·Ρ€Π°Ρ‡Π½Ρ‹ΠΉ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ позволяСт PostgreSQL эффСктивно Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с Π΄Π°Π½Π½Ρ‹ΠΌΠΈ, ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ°ΡŽΡ‰ΠΈΠΌΠΈ Ρ€Π°Π·ΠΌΠ΅Ρ€ страницы, ΠΎΠ΄Π½Π°ΠΊΠΎ Π΅Π³ΠΎ использованиС ΠΌΠΎΠΆΠ΅Ρ‚ сущСствСнно Π²Π»ΠΈΡΡ‚ΡŒ Π½Π° ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ, особСнно ΠΏΡ€ΠΈ частом доступС ΠΊ большим JSONB-значСниям.

Π₯ΠΎΠ΄ Ρ€Π°Π±ΠΎΡ‚Ρ‹

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ…

Для Π½Π°Ρ‡Π°Π»Π° ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΠΌΡΡ ΠΊ сСрвСру PostgreSQL:

psql -U postgres

Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π±Π°Π·Ρƒ Π΄Π°Π½Π½Ρ‹Ρ… imdb:

CREATE DATABASE "imdb";

ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Ρ„Π°ΠΉΠ»Π° со списком Π°ΠΊΡ‚Π΅Ρ€ΠΎΠ² ΠΈ ΠΈΡ… Ρ€ΠΎΠ»Π΅ΠΉ

Π‘ΠΊΡ€ΠΈΠΏΡ‚ parse.py ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Ρ„Π°ΠΉΠ»Π° actors.list.txt ΠΈΠ· Π½Π°Π±ΠΎΡ€Π° Π΄Π°Π½Π½Ρ‹Ρ… IMDB ΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ этих Π΄Π°Π½Π½Ρ‹Ρ… Π² PostgreSQL Π±Π°Π·Ρƒ Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠ°ΠΊ трСбуСтся Π² тСхничСском Π·Π°Π΄Π°Π½ΠΈΠΈ.

Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ

  • psycopg2 - для взаимодСйствия с PostgreSQL.
  • json - для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с JSON-Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΎΠΌ Π΄Π°Π½Π½Ρ‹Ρ….
  • re - для использования рСгулярных Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ ΠΏΡ€ΠΈ парсингС Ρ„Π°ΠΉΠ»Π°.
  • time - для измСрСния Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ выполнСния Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… этапов.
  • concurrent.futures.ThreadPoolExecutor - для ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ….
  • os - для получСния систСмной ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ.
  • psycopg2.extras.execute_values - для ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΉ ΠΏΠ°ΠΊΠ΅Ρ‚Π½ΠΎΠΉ вставки Π΄Π°Π½Π½Ρ‹Ρ….
  • prettytable - для Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ Π²Ρ‹Π²ΠΎΠ΄Π° статистики Π² консоль.

АрхитСктура Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ

Π‘ΠΊΡ€ΠΈΠΏΡ‚ ΠΎΡ€Π³Π°Π½ΠΈΠ·ΠΎΠ²Π°Π½ ΠΏΠΎ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΡƒ поэтапной ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ…:

  1. ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊ Π‘Π” - с ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ PostgreSQL.
  2. Π§Ρ‚Π΅Π½ΠΈΠ΅ Ρ„Π°ΠΉΠ»Π° - Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ° Ρ„Π°ΠΉΠ»Π° actors.list.txt Π² ΠΏΠ°ΠΌΡΡ‚ΡŒ.
  3. Π Π°Π·Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… - Ρ€Π°Π·Π±ΠΈΠ΅Π½ΠΈΠ΅ Ρ„Π°ΠΉΠ»Π° Π½Π° Π±Π»ΠΎΠΊΠΈ Π°ΠΊΡ‚Π΅Ρ€ΠΎΠ² ΠΏΠΎ пустым строкам: для Ρ€ΠΎΠ»ΠΈ Π°ΠΊΡ‚Ρ‘Ρ€Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡŒΡΡ ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚Π΅Π»ΡŒ LF, для Π°ΠΊΡ‚Ρ‘Ρ€ΠΎΠ² - Π΄Π²Π° LF.
  4. ΠŸΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Π°Ρ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° - ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½Ρ‹ΠΉ парсинг Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΠ± Π°ΠΊΡ‚Π΅Ρ€Π°Ρ… ΠΈ ΠΈΡ… ролях.
  5. ΠŸΠ°ΠΊΠ΅Ρ‚Π½Π°Ρ вставка - эффСктивная Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… Π² Π‘Π”.
  6. Π‘Π±ΠΎΡ€ ΠΈ Π²Ρ‹Π²ΠΎΠ΄ статистики - Π°Π½Π°Π»ΠΈΠ· ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΈ Π²Ρ‹Π²ΠΎΠ΄ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ².

ΠšΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ парсинга Π΄Π°Π½Π½Ρ‹Ρ…

  • parse_name(name_text) - ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅Ρ‚ имя ΠΈ Ρ„Π°ΠΌΠΈΠ»ΠΈΡŽ Π°ΠΊΡ‚Π΅Ρ€Π° ΠΈΠ· строки Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° "Ѐамилия, Имя".
  • parse_role(raw_title) - Ρ€Π°Π·Π±ΠΈΡ€Π°Π΅Ρ‚ строку с описаниСм Ρ€ΠΎΠ»ΠΈ Π½Π° ΡΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΠΈΠ΅:
    • Π½Π°Π·Π²Π°Π½ΠΈΠ΅ Ρ„ΠΈΠ»ΡŒΠΌΠ°/сСриала;
    • Π³ΠΎΠ΄ выпуска;
    • Ρ‚ΠΈΠΏΡ‹ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Π° (TV, V, VG ΠΈ Ρ‚.Π΄.);
    • Π½Π°Π·Π²Π°Π½ΠΈΠ΅ сСрии ΠΈ Π΅Ρ‘ Π½ΠΎΠΌΠ΅Ρ€;
    • имя пСрсонаТа;
    • Π½ΠΎΠΌΠ΅Ρ€ Π² Ρ‚ΠΈΡ‚Ρ€Π°Ρ…;
    • Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π½Ρ‹Π΅ ΠΈΠΌΠ΅Π½Π° пСрсонаТа;
  • parse_actor_data(actor_block) - ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ вСсь Π±Π»ΠΎΠΊ тСкста ΠΎΠ± ΠΎΠ΄Π½ΠΎΠΌ Π°ΠΊΡ‚Π΅Ρ€Π΅.

Π’ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

  • clean_string(text) - удаляСт Π΄Π²ΠΎΠΉΠ½Ρ‹Π΅ ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠΈ ΠΈΠ· строк.
  • process_chunk_of_actors(actors_chunk) - ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π³Ρ€ΡƒΠΏΠΏΡ‹ Π°ΠΊΡ‚Π΅Ρ€ΠΎΠ² (для ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ выполнСния).
  • chunk_list(lst, chunk_size) - Ρ€Π°Π·Π±ΠΈΠ΅Π½ΠΈΠ΅ списка Π½Π° подсписки.
  • format_time(seconds) - ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ сСкунды Π² Ρ‡ΠΈΡ‚Π°Π΅ΠΌΡ‹ΠΉ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ.

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π‘Π”

  • create_schema(cursor) - создаСт структуру Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ Π² Π‘Π”.
  • main() - основная функция, ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½ΠΈΡ€ΡƒΡŽΡ‰Π°Ρ вСсь процСсс.

ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ

  1. ΠŸΡ€Π΅Π΄ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡ†ΠΈΡ рСгулярных Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ - для Π±ΠΎΠ»Π΅Π΅ быстрого парсинга.
  2. ΠœΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½Π°Ρ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° - использованиС ThreadPoolExecutor с ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΌ количСством ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², зависящим ΠΎΡ‚ числа ядСр процСссора.
  3. ΠŸΠ°ΠΊΠ΅Ρ‚Π½Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ - Π³Ρ€ΡƒΠΏΠΏΠΈΡ€ΠΎΠ²ΠΊΠ° ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ вставки Π΄Π°Π½Π½Ρ‹Ρ….
  4. ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡ памяти - своСврСмСнноС освобоТдСниС памяти послС использования ΠΎΠ±ΡŠΠ΅ΠΌΠ½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ….
  5. Настройка PostgreSQL - оптимизация ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ²:
    • work_mem=64MB - увСличСнная ΠΏΠ°ΠΌΡΡ‚ΡŒ для ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ сортировки ΠΈ Ρ…Π΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ;
    • statement_timeout=0 - ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ Π½Π° врСмя выполнСния запроса.

Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° Π΄Π°Π½Π½Ρ‹Ρ…

Π‘ΠΊΡ€ΠΈΠΏΡ‚ создаСт Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ actors со ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌΠΈ полями:

  • id - Π°Π²Ρ‚ΠΎΠΈΠ½ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚Π½Ρ‹ΠΉ ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½Ρ‹ΠΉ ΠΊΠ»ΡŽΡ‡.
  • ActorFirstName - имя Π°ΠΊΡ‚Π΅Ρ€Π°.
  • ActorSecondName - фамилия Π°ΠΊΡ‚Π΅Ρ€Π°.
  • RolesName - информация ΠΎ ролях Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ JSONB.
CREATE TABLE IF NOT EXISTS actors (
    id SERIAL PRIMARY KEY,
    ActorFirstName TEXT,
    ActorSecondName TEXT,
    RolesName JSONB
);

ПолС RolesName содСрТит массив ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… описываСт ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΡƒΡŽ Ρ€ΠΎΠ»ΡŒ Π°ΠΊΡ‚Π΅Ρ€Π° со всСми Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π°ΠΌΠΈ, ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΌΠΈ Π² Π·Π°Π΄Π°Π½ΠΈΠΈ (Π½Π°Π·Π²Π°Π½ΠΈΠ΅, Π³ΠΎΠ΄, пСрсонаТ ΠΈ Ρ‚.Π΄.).

ΠœΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³ ΠΈ статистика

Π‘ΠΊΡ€ΠΈΠΏΡ‚ отслСТиваСт врСмя выполнСния ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ этапа ΠΈ Π² ΠΊΠΎΠ½Ρ†Π΅ Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ Π΄Π΅Ρ‚Π°Π»ΡŒΠ½ΡƒΡŽ статистику:

  • ΠžΠ±Ρ‰Π΅Π΅ врСмя выполнСния ΠΈ распрСдСлСниС ΠΏΠΎ этапам.
  • ΠŸΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ (Π°ΠΊΡ‚Π΅Ρ€ΠΎΠ² ΠΈ Ρ€ΠΎΠ»Π΅ΠΉ Π² сСкунду).
  • Π‘ΠΎΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΠ΅ количСства Ρ€ΠΎΠ»Π΅ΠΉ ΠΊ Π°ΠΊΡ‚Π΅Ρ€Π°ΠΌ.

ΠžΡ‡ΠΈΡΡ‚ΠΊΠ° Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ ΠΈ созданиС индСксов

ΠžΡ‡ΠΈΡΡ‚ΠΊΠ° Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ (TRUNCATE)

Π’ скриптС ΠΏΠ΅Ρ€Π΅Π΄ массовой вставкой Π΄Π°Π½Π½Ρ‹Ρ… выполняСтся полная очистка Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ actors для обСспСчСния "чистых" запусков:

# ΠžΡ‡ΠΈΡ‰Π°Π΅ΠΌ Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ ΠΏΠ΅Ρ€Π΅Π΄ вставкой
truncate_start = time.time()
# Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΈΡΠΏΡ€ΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ "RESTART IDENTITY", Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠ±Ρ€ΠΎΡΠΈΡ‚ΡŒ счСтчик ID
cursor.execute("TRUNCATE TABLE actors RESTART IDENTITY")
timing["truncate"] = time.time() - truncate_start

Π’Π°ΠΆΠ½Ρ‹Π΅ аспСкты этого этапа:

  • Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Π° TRUNCATE TABLE вмСсто DELETE FROM для Π±ΠΎΠ»Π΅Π΅ эффСктивной очистки, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ½Π° Π½Π΅ сканируСт Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ ΠΈ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ мСньшС Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΠΊ рСсурсов.
  • ΠžΠΏΡ†ΠΈΡ RESTART IDENTITY сбрасываСт счСтчик Π°Π²Ρ‚ΠΎΠΈΠ½ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚Π½ΠΎΠ³ΠΎ ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½ΠΎΠ³ΠΎ ΠΊΠ»ΡŽΡ‡Π° id Π΄ΠΎ Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ значСния, Ρ‡Ρ‚ΠΎ обСспСчиваСт ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹Π΅ ID ΠΏΡ€ΠΈ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½Ρ‹Ρ… запусках.
  • ВрСмя выполнСния этой ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ измСряСтся ΠΈ сохраняСтся для ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ Π°Π½Π°Π»ΠΈΠ·Π° ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ.

БозданиС индСксов

ПослС Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ всСх Π΄Π°Π½Π½Ρ‹Ρ… скрипт создаСт спСциализированныС индСксы для ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… запросов:

# ВрСмя создания индСксов
index_start = time.time()
print("БозданиС индСксов...")

# Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ индСкс для ускорСния поиска, Ссли Π΅Π³ΠΎ Π½Π΅Ρ‚
cursor.execute(
    """
    CREATE INDEX IF NOT EXISTS idx_actors_names
    ON actors (ActorFirstName, ActorSecondName)
    """
)

# Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ GIN-индСкс для поиска ΠΏΠΎ JSON, Ссли Π΅Π³ΠΎ Π½Π΅Ρ‚
cursor.execute(
    """
    CREATE INDEX IF NOT EXISTS idx_actors_roles
    ON actors USING GIN (RolesName jsonb_path_ops)
    """
)

conn.commit()

timing["index"] = time.time() - index_start
print(f"БозданиС индСксов: {format_time(timing['index'])}")

Π’Π°ΠΆΠ½Ρ‹Π΅ Π΄Π΅Ρ‚Π°Π»ΠΈ этого этапа:

  • БоздаСтся составной B-tree индСкс idx_actors_names ΠΏΠΎ столбцам ActorFirstName ΠΈ ActorSecondName, Ρ‡Ρ‚ΠΎ ускоряСт поиск ΠΈ сортировку ΠΏΠΎ ΠΈΠΌΠ΅Π½Π°ΠΌ Π°ΠΊΡ‚Π΅Ρ€ΠΎΠ².
  • БоздаСтся спСциализированный GIN (Generalized Inverted Index) индСкс idx_actors_roles для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с JSONB-ΠΏΠΎΠ»Π΅ΠΌ RolesName. Π­Ρ‚ΠΎΡ‚ Ρ‚ΠΈΠΏ индСкса ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½ для полнотСкстового поиска ΠΈ поиска ΠΏΠΎ элСмСнтам/ΠΊΠ»ΡŽΡ‡Π°ΠΌ Π² JSON-структурах.
  • ΠžΠΏΡ†ΠΈΡ jsonb_path_ops ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ индСкс ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ для ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² поиска ΠΏΠΎ ΠΏΡƒΡ‚ΠΈ Π² JSONB ΠΈ Π΄Π΅Π»Π°Π΅Ρ‚ поиск Π±ΠΎΠ»Π΅Π΅ эффСктивным для Π·Π°Π΄Π°Π½ΠΈΠΉ ΠΈΠ· тСхничСского задания.
  • ПослС создания индСксов выполняСтся явный commit Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ для фиксации ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ.
  • ВрСмя создания индСксов измСряСтся ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ это рСсурсоСмкая опСрация, особСнно для Π±ΠΎΠ»ΡŒΡˆΠΈΡ… объСмов Π΄Π°Π½Π½Ρ‹Ρ….

Π”Π°Π½Π½Ρ‹Π΅ индСксы критичСски Π²Π°ΠΆΠ½Ρ‹ для эффСктивного выполнСния запросов ΠΈΠ· тСхничСского задания, особСнно Ρ‚Π΅Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π½Π° Π²Ρ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ Π² JSONB ΠΈ jsonpath.

Установка зависимостСй

Для Ρ€Π°Π±ΠΎΡ‚Ρ‹ скрипта Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ зависимости. Π‘Π΄Π΅Π»Π°Ρ‚ΡŒ это ΠΌΠΎΠΆΠ½ΠΎ создав Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠ΅ ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠ΅ ΠΈ установив зависимости ΠΈΠ· Ρ„Π°ΠΉΠ»Π° requirements.txt:

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Π€Π°ΠΉΠ» requirements.txt содСрТит ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ зависимости:

psycopg2>=2.9.10
prettytable>=3.15.1
pandas>=2.2.3
matplotlib>=3.10.1
numpy>=2.2.4
scipy>=1.15.2

НСкоторыС ΠΈΠ· описанных зависимостСй понадобятся Π² ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… этапах для Π°Π½Π°Π»ΠΈΠ·Π° ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΈ построСния Π³Ρ€Π°Ρ„ΠΈΠΊΠΎΠ².

Запуск скрипта

Для запуска скрипта Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ:

python ./0-parse/parse.py

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π²Ρ‹Π²ΠΎΠ΄Π° Ρ€Π°Π±ΠΎΡ‚Ρ‹ скрипта

ΠŸΠΎΠ»Π½Ρ‹ΠΉ листинг процСсса ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Ρ„Π°ΠΉΠ»Π° ΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ… Π² Π‘Π”:

ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊ Π‘Π”: 0.14с
Π§Ρ‚Π΅Π½ΠΈΠ΅ Ρ„Π°ΠΉΠ»Π°...
Π€Π°ΠΉΠ» ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π½, Ρ€Π°Π·ΠΌΠ΅Ρ€: 1235.54 ΠœΠ‘, врСмя: 4.88с
Π Π°Π·Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… Π½Π° Π±Π»ΠΎΠΊΠΈ Π°ΠΊΡ‚Π΅Ρ€ΠΎΠ²...
ВсСго Π½Π°ΠΉΠ΄Π΅Π½ΠΎ Π±Π»ΠΎΠΊΠΎΠ² Π°ΠΊΡ‚Π΅Ρ€ΠΎΠ²: 2673784, врСмя: 1.08с
ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π΄Π°Π½Π½Ρ‹Ρ…...
ΠŸΠΎΡ‚ΠΎΠΊΠΎΠ² для ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ: 24
ВсСго ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π½ΠΎ Π°ΠΊΡ‚Π΅Ρ€ΠΎΠ²: 2673784, Ρ€ΠΎΠ»Π΅ΠΉ: 19993184, врСмя: 2ΠΌ 9.07с
Вставка Π΄Π°Π½Π½Ρ‹Ρ… Π² Π±Π°Π·Ρƒ...
ВставлСно 100000 ΠΈΠ· 2673784 записСй (3.7%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 1ΠΌ 54.50с
ВставлСно 200000 ΠΈΠ· 2673784 записСй (7.5%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 1ΠΌ 38.30с
ВставлСно 300000 ΠΈΠ· 2673784 записСй (11.2%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 1ΠΌ 34.01с
ВставлСно 400000 ΠΈΠ· 2673784 записСй (15.0%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 1ΠΌ 31.12с
ВставлСно 500000 ΠΈΠ· 2673784 записСй (18.7%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 1ΠΌ 26.43с
ВставлСно 600000 ΠΈΠ· 2673784 записСй (22.4%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 1ΠΌ 22.42с
ВставлСно 700000 ΠΈΠ· 2673784 записСй (26.2%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 1ΠΌ 17.85с
ВставлСно 800000 ΠΈΠ· 2673784 записСй (29.9%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 1ΠΌ 13.97с
ВставлСно 900000 ΠΈΠ· 2673784 записСй (33.7%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 1ΠΌ 10.28с
ВставлСно 1000000 ΠΈΠ· 2673784 записСй (37.4%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 1ΠΌ 5.87с
ВставлСно 1100000 ΠΈΠ· 2673784 записСй (41.1%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 1ΠΌ 2.04с
ВставлСно 1200000 ΠΈΠ· 2673784 записСй (44.9%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 57.91с
ВставлСно 1300000 ΠΈΠ· 2673784 записСй (48.6%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 53.74с
ВставлСно 1400000 ΠΈΠ· 2673784 записСй (52.4%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 49.75с
ВставлСно 1500000 ΠΈΠ· 2673784 записСй (56.1%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 45.86с
ВставлСно 1600000 ΠΈΠ· 2673784 записСй (59.8%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 42.08с
ВставлСно 1700000 ΠΈΠ· 2673784 записСй (63.6%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 38.04с
ВставлСно 1800000 ΠΈΠ· 2673784 записСй (67.3%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 33.71с
ВставлСно 1900000 ΠΈΠ· 2673784 записСй (71.1%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 29.88с
ВставлСно 2000000 ΠΈΠ· 2673784 записСй (74.8%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 25.99с
ВставлСно 2100000 ΠΈΠ· 2673784 записСй (78.5%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 22.10с
ВставлСно 2200000 ΠΈΠ· 2673784 записСй (82.3%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 18.25с
ВставлСно 2300000 ΠΈΠ· 2673784 записСй (86.0%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 14.37с
ВставлСно 2400000 ΠΈΠ· 2673784 записСй (89.8%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 10.50с
ВставлСно 2500000 ΠΈΠ· 2673784 записСй (93.5%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 6.69с
ВставлСно 2600000 ΠΈΠ· 2673784 записСй (97.2%)... ΠžΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ: 2.84с
Вставка Π΄Π°Π½Π½Ρ‹Ρ…: 1ΠΌ 42.00с
БозданиС индСксов...
БозданиС индСксов: 1м 10.10с
+--------------------------------------------------+
|      Π˜Π’ΠžΠ“ΠžΠ’ΠΠ― БВАВИБВИКА Π’Π Π•ΠœΠ•ΠΠ˜ Π’Π«ΠŸΠžΠ›ΠΠ•ΠΠ˜Π―      |
+------------------------+-----------+-------------+
| Π­Ρ‚Π°ΠΏ                   | ВрСмя     | % ΠΎΡ‚ ΠΎΠ±Ρ‰Π΅Π³ΠΎ |
+------------------------+-----------+-------------+
| ΠžΠ±Ρ‰Π΅Π΅ врСмя выполнСния | 5ΠΌ 7.54с  | 100.0%      |
| ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊ Π‘Π”       | 0.14с     | 0.0%        |
| Π§Ρ‚Π΅Π½ΠΈΠ΅ Ρ„Π°ΠΉΠ»Π°           | 4.88с     | 1.6%        |
| РазбиСниС на блоки     | 1.08с     | 0.3%        |
| ΠžΡ‡ΠΈΡΡ‚ΠΊΠ° Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹        | 0.10с     | 0.0%        |
| ΠŸΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ° частСй      | 0.17с     | 0.1%        |
| ΠŸΠ°Ρ€ΡΠΈΠ½Π³ Π΄Π°Π½Π½Ρ‹Ρ…         | 2ΠΌ 9.07с  | 42.0%       |
| Вставка Π΄Π°Π½Π½Ρ‹Ρ…         | 1ΠΌ 42.00с | 33.2%       |
| БозданиС индСксов      | 1м 10.10с | 22.8%       |
+------------------------+-----------+-------------+
+----------------------------------------------+
|        БВАВИБВИКА ΠŸΠ ΠžΠ˜Π—Π’ΠžΠ”Π˜Π’Π•Π›Π¬ΠΠžΠ‘Π’Π˜         |
+----------------------------------+-----------+
| ΠœΠ΅Ρ‚Ρ€ΠΈΠΊΠ°                          | Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅  |
+----------------------------------+-----------+
| Π‘ΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ (Π°ΠΊΡ‚Π΅Ρ€ΠΎΠ²/сСк) | 20716.44  |
| Π‘ΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ (Ρ€ΠΎΠ»Π΅ΠΉ/сСк)   | 154906.93 |
| Π‘ΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ вставки (Π°ΠΊΡ‚Π΅Ρ€ΠΎΠ²/сСк)   | 26212.65  |
| ΠžΠ±Ρ‰Π°Ρ ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ (Π°ΠΊΡ‚Π΅Ρ€ΠΎΠ²/сСк)     | 8694.00   |
| Π‘ΠΎΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΠ΅ Ρ€ΠΎΠ»Π΅ΠΉ ΠΊ Π°ΠΊΡ‚Π΅Ρ€Π°ΠΌ      | 7.48      |
+----------------------------------+-----------+

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹

Для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π²Ρ‹Π²Π΅Π΄Π΅ΠΌ ΠΏΠ΅Ρ€Π²Ρ‹Π΅ 3 записи ΠΈΠ· Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ actors:

psql --tuples-only -U postgres -d imdb -c "select * from actors limit 3;"
id actorfirstname actorsecondname rolesname
1 Buffy #1 {"roles": [{"year": "2015", "title": "Closet Monster", "credit": "31", "character name": "Buffy 4"}]}
2 Claw $ {"roles": [{"year": "2012", "title": "OnCreativity", "character name": "Himself"}]}
3 Homo $ {"roles": [{"year": "1986", "title": "Nykytaiteen museo", "credit": "25", "character name": "Himself"}, {"year": "1985", "title": "Suuri illusioni", "credit": "22", "character name": "Guests"}]}

ЗафиксируСм количСство строк Π² ΠΈΡ‚ΠΎΠ³ΠΎΠ²ΠΎΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Π΅ actors - 2'673'784:

psql -U postgres -d imdb -c "select count(*) from actors;"
  count  
---------
 2673784
(1 row)

Запросы с использованиСм API PostgreSQL для JSONB

Запуск запросов

Запустим Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Ρ… запросов ΠΈΠ· Ρ„Π°ΠΉΠ»Π° ./1-queries/queries.sql Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΠ² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ Π² Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π΅:

psql -U postgres -d imdb -f ./1-queries/queries.sql | cat

1.1. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π½Π° Π²Ρ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ ΠΈ сущСствованиС JSONB

Запрос 1: Поиск Π°ΠΊΡ‚Ρ‘Ρ€ΠΎΠ², ΡΡ‹Π³Ρ€Π°Π²ΡˆΠΈΡ… Π”Π΅Ρ‚Π΅ΠΊΡ‚ΠΈΠ²Π°

SELECT
    ActorFirstName,
    ActorSecondName
FROM
    actors
WHERE
    RolesName @> '{"roles": [{"character name": "Detective"}]}'
LIMIT 10;

ОписаниС:

  • ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ @> (содСрТит/Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚) - провСряСт, являСтся Π»ΠΈ Π»Π΅Π²Ρ‹ΠΉ JSONB-Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ супСрмноТСством ΠΏΡ€Π°Π²ΠΎΠ³ΠΎ.
  • Запрос ΠΈΡ‰Π΅Ρ‚ записи, Π³Π΄Π΅ Π² массивС roles сущСствуСт хотя Π±Ρ‹ ΠΎΠ΄ΠΈΠ½ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ с ΠΏΠΎΠ»Π΅ΠΌ "character name" Ρ€Π°Π²Π½Ρ‹ΠΌ "Detective".
  • ΠŸΡ€Π΅ΠΈΠΌΡƒΡ‰Π΅ΡΡ‚Π²ΠΎ: ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ GIN-индСкс ΠΏΠΎ JSONB, Ρ‡Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ поиск эффСктивным.
  • LIMIT 10 ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ Π²Ρ‹Π²ΠΎΠ΄ ΠΏΠ΅Ρ€Π²Ρ‹ΠΌΠΈ 10 совпадСниями.

Запрос 2: Π€ΠΈΠ»ΡŒΠΌΡ‹ 2002 Π³ΠΎΠ΄Π°, Π³Π΄Π΅ Π°ΠΊΡ‚Π΅Ρ€ ΠΈΠ³Ρ€Π°Π» самого сСбя

SELECT
    ActorFirstName,
    ActorSecondName,
    RolesName -> 'roles' -> 0 ->> 'title'
FROM
    actors
WHERE
    RolesName @> '{"roles": [{"year": "2002"}]}'
    AND RolesName @> '{"roles": [{"character name": "Himself"}]}'
LIMIT 10;

ОписаниС:

  • Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Π΄Π²Π° условия с ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠΌ @>, соСдинСнныС Ρ‡Π΅Ρ€Π΅Π· AND.
  • ΠŸΠ΅Ρ€Π²ΠΎΠ΅ условиС: ΠΈΡ‰Π΅Ρ‚ Ρ€ΠΎΠ»ΠΈ с Π³ΠΎΠ΄ΠΎΠΌ "2002".
  • Π’Ρ‚ΠΎΡ€ΠΎΠ΅ условиС: ΠΈΡ‰Π΅Ρ‚ Ρ€ΠΎΠ»ΠΈ с ΠΈΠΌΠ΅Π½Π΅ΠΌ пСрсонаТа "Himself".
  • ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ -> - ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅Ρ‚ ΠΏΠΎΠ»Π΅ ΠΈΠ· JSONB ΠΊΠ°ΠΊ JSONB-ΠΎΠ±ΡŠΠ΅ΠΊΡ‚.
  • ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ ->> - ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅Ρ‚ ΠΏΠΎΠ»Π΅ ΠΈΠ· JSONB ΠΊΠ°ΠΊ тСкст (TEXT).
  • RolesName->'roles'->0->>'title' - ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π²ΠΎΠΉ Ρ€ΠΎΠ»ΠΈ ΠΈΠ· списка.

Запрос 3: ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° сущСствования ΠΊΠ»ΡŽΡ‡Π°

SELECT
    COUNT(*)
FROM
    actors
WHERE
    RolesName -> 'roles' -> 0 ? 'type1';;

ОписаниС:

  • ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ ? - провСряСт сущСствованиС ΠΊΠ»ΡŽΡ‡Π° Π² JSONB-ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π΅ (Π±Π΅Π· ΡƒΡ‡Π΅Ρ‚Π° Π΅Π³ΠΎ значСния).
  • RolesName->'roles'->0 - ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΊ ΠΏΠ΅Ρ€Π²ΠΎΠΉ Ρ€ΠΎΠ»ΠΈ Π² массивС Ρ€ΠΎΠ»Π΅ΠΉ.
  • Запрос подсчитываСт количСство Π°ΠΊΡ‚Π΅Ρ€ΠΎΠ², Ρƒ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π² ΠΏΠ΅Ρ€Π²ΠΎΠΉ Ρ€ΠΎΠ»ΠΈ ΡƒΠΊΠ°Π·Π°Π½ Ρ‚ΠΈΠΏ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Π° (type1).

1.2. ΠžΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΏΠΎ индСксу ΠΊ элСмСнтам JSONB

Запрос 4: ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… ΠΎ ΠΏΠ΅Ρ€Π²ΠΎΠΉ Ρ€ΠΎΠ»ΠΈ

SELECT
    ActorFirstName,
    ActorSecondName,
    RolesName -> 'roles' -> 0 ->> 'title' AS first_role_title,
    RolesName -> 'roles' -> 0 ->> 'year' AS first_role_year
FROM
    actors
LIMIT 15;

ОписаниС:

  • Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ доступа ΠΊ элСмСнтам массива ΠΏΠΎ индСксу.
  • ->0 - ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΊ ΠΏΠ΅Ρ€Π²ΠΎΠΌΡƒ элСмСнту массива (Π² PostgreSQL индСксация начинаСтся с 0).
  • ->>'title' - ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΠ»ΡŽΡ‡Π° 'title' ΠΊΠ°ΠΊ тСкст.
  • AS - Π·Π°Π΄Π°Π΅Ρ‚ псСвдонимы для Π²Ρ‹Ρ…ΠΎΠ΄Π½Ρ‹Ρ… столбцов.
  • Π’Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ ΠΈΠΌΠ΅Π½Π° Π°ΠΊΡ‚Π΅Ρ€ΠΎΠ² ΠΈ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎΠ± ΠΈΡ… ΠΏΠ΅Ρ€Π²ΠΎΠΉ Ρ€ΠΎΠ»ΠΈ (Π½Π°Π·Π²Π°Π½ΠΈΠ΅ ΠΈ Π³ΠΎΠ΄).

Запрос 5: Π Π΅ΠΉΡ‚ΠΈΠ½Π³ Π°ΠΊΡ‚Π΅Ρ€ΠΎΠ² ΠΏΠΎ количСству Ρ€ΠΎΠ»Π΅ΠΉ

SELECT
    ActorFirstName,
    ActorSecondName,
    jsonb_array_length(RolesName -> 'roles') AS roles_count
FROM
    actors
ORDER BY
    roles_count DESC
LIMIT 10;

ОписаниС:

  • jsonb_array_length() - встроСнная функция, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰Π°Ρ количСство элСмСнтов Π² JSONB-массивС.
  • ORDER BY roles_count DESC - сортировка Π² порядкС убывания количСства Ρ€ΠΎΠ»Π΅ΠΉ.
  • Π’Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ ВОП-10 Π°ΠΊΡ‚Π΅Ρ€ΠΎΠ² с наибольшим количСством Ρ€ΠΎΠ»Π΅ΠΉ Π² Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ….

1.3. ИспользованиС языка JSONPath

Запрос 6: АктСры Π² Π³Π»Π°Π²Π½Ρ‹Ρ… ролях послС 2010 Π³ΠΎΠ΄Π°

SELECT
    ActorFirstName,
    ActorSecondName
FROM
    actors
WHERE
    jsonb_path_exists(RolesName, '$.roles[*] ? (@.year >= "2010" && @.credit == "1")')
LIMIT 10;

ОписаниС:

  • jsonb_path_exists() - функция, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡŽΡ‰Π°Ρ сущСствованиС элСмСнтов, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… JSONPath-Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΡŽ.
  • $ - ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠΉ элСмСнт Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°.
  • roles[*] - ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΊΠΎ всСм элСмСнтам массива roles.
  • ? - ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π° Π² JSONPath.
  • @ - Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ элСмСнт ΠΏΡ€ΠΈ ΠΈΡ‚Π΅Ρ€Π°Ρ†ΠΈΠΈ.
  • @.year >= "2010" && @.credit == "1" - условиС: Π³ΠΎΠ΄ большС ΠΈΠ»ΠΈ Ρ€Π°Π²Π΅Π½ 2010 И Π½ΠΎΠΌΠ΅Ρ€ Π² Ρ‚ΠΈΡ‚Ρ€Π°Ρ… Ρ€Π°Π²Π΅Π½ 1.
  • Находит Π°ΠΊΡ‚Π΅Ρ€ΠΎΠ², ΡΡ‹Π³Ρ€Π°Π²ΡˆΠΈΡ… Π³Π»Π°Π²Π½ΡƒΡŽ Ρ€ΠΎΠ»ΡŒ (credit=1) Π² Ρ„ΠΈΠ»ΡŒΠΌΠ°Ρ… 2010 Π³ΠΎΠ΄Π° ΠΈ ΠΏΠΎΠ·ΠΆΠ΅.

Запрос 7: Поиск Ρ€ΠΎΠ»Π΅ΠΉ с "Doctor" Π² ΠΈΠΌΠ΅Π½ΠΈ пСрсонаТа

SELECT
    ActorFirstName,
    ActorSecondName,
    jsonb_path_query_array(RolesName, '$.roles[*] ? (@."character name" like_regex ".*Doctor.*")') AS doctor_roles
FROM
    actors
WHERE
    jsonb_path_exists(RolesName, '$.roles[*] ? (@."character name" like_regex ".*Doctor.*")')
LIMIT 5;

ОписаниС:

  • jsonb_path_query_array() - собираСт Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ JSONPath-запроса Π² JSONB-массив.
  • like_regex - ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ поиска ΠΏΠΎ рСгулярному Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΡŽ Π² JSONPath.
  • ".*Doctor.*" - рСгулярноС Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ для поиска строк, содСрТащих "Doctor".
  • Π’ условии WHERE ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ jsonb_path_exists() для Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ†ΠΈΠΈ Π°ΠΊΡ‚Π΅Ρ€ΠΎΠ².
  • Запрос Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎΠ± Π°ΠΊΡ‚Π΅Ρ€Π°Ρ… ΠΈ ΠΈΡ… ролях, Π³Π΄Π΅ имя пСрсонаТа содСрТит "Doctor".

1.4. ИспользованиС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ для JSONB

Запрос 8: Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π°Π³Ρ€Π΅Π³ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎΠ± Π°ΠΊΡ‚Π΅Ρ€Π΅

SELECT
    ActorFirstName,
    ActorSecondName,
    jsonb_build_object('name', ActorFirstName || ' ' || ActorSecondName, 'roles_count', jsonb_array_length(RolesName -> 'roles'), 'first_role', RolesName -> 'roles' -> 0) AS actor_summary
FROM
    actors
LIMIT 10;

ОписаниС:

  • jsonb_build_object() - создаСт Π½ΠΎΠ²Ρ‹ΠΉ JSONB-ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΠ· ΠΏΠ°Ρ€ ΠΊΠ»ΡŽΡ‡-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅.
  • || - ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ ΠΊΠΎΠ½ΠΊΠ°Ρ‚Π΅Π½Π°Ρ†ΠΈΠΈ строк Π² PostgreSQL.
  • Π€ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅Ρ‚ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π°ΠΊΡ‚Π΅Ρ€Π° Π½ΠΎΠ²Ρ‹ΠΉ JSON-ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ с трСмя полями:
    • name: ΠΏΠΎΠ»Π½ΠΎΠ΅ имя Π°ΠΊΡ‚Π΅Ρ€Π° (конкатСнация ΠΈΠΌΠ΅Π½ΠΈ ΠΈ Ρ„Π°ΠΌΠΈΠ»ΠΈΠΈ);
    • roles_count: количСство Ρ€ΠΎΠ»Π΅ΠΉ (Ρ‡Π΅Ρ€Π΅Π· Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ jsonb_array_length);
    • first_role: полная информация ΠΎ ΠΏΠ΅Ρ€Π²ΠΎΠΉ Ρ€ΠΎΠ»ΠΈ ΠΊΠ°ΠΊ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΉ JSON-ΠΎΠ±ΡŠΠ΅ΠΊΡ‚.

Запрос 9: Π Π°Π·Π²Π΅Ρ€Ρ‚Ρ‹Π²Π°Π½ΠΈΠ΅ массива Ρ€ΠΎΠ»Π΅ΠΉ Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ строки

SELECT
    ActorFirstName,
    ActorSecondName,
    jsonb_array_elements(RolesName -> 'roles') ->> 'title' AS role_title
FROM
    actors
LIMIT 20;

ОписаниС:

  • jsonb_array_elements() - функция с Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹ΠΌ Π½Π°Π±ΠΎΡ€ΠΎΠΌ (set-returning function).
  • ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ элСмСнт массива roles Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΡƒΡŽ строку Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°.
  • Для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π°ΠΊΡ‚Π΅Ρ€Π° Π±ΡƒΠ΄Π΅Ρ‚ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½ΠΎ ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ строк, сколько Ρƒ Π½Π΅Π³ΠΎ Ρ€ΠΎΠ»Π΅ΠΉ.
  • ->>'title' - ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ Ρ€ΠΎΠ»ΠΈ Π² тСкстовом Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅.
  • Π“Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ "плоский" список Ρ€ΠΎΠ»Π΅ΠΉ вмСсто Π²Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠΉ структуры.

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ выполнСния запросов

НиТС прСдставлСны Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ выполнСния всСх Π²Ρ‹ΡˆΠ΅ΡƒΠΏΠΎΠΌΡΠ½ΡƒΡ‚Ρ‹Ρ… запросов с использованиСм API PostgreSQL для JSONB:

 actorfirstname |     actorsecondname      
----------------+--------------------------
 Harry          | 'The Carpenter' Mansoori
 Peter          | Aanensen
 Frank          | Aaron
 Allan          | Aarons
 Asa            | Aarons
 Poul           | Aars
 Tony           | Abatemarco
 Serge          | Abattucci
 Marc           | Abbink
 David          | Abbott
(10 rows)

 actorfirstname | actorsecondname |                   ?column?                    
----------------+-----------------+-----------------------------------------------
 Guilford       | Adams           | Boys Don't Cry
 JosΓ©           | 'El FrancΓ©s'    | Alma gitana
 Sander         | 't Sas          | De wereld draait door
                | .38 Special     | 38 Special: Live at Sturgis
 Angry          | Anderson        | At Last... Bullamakanka: The Motion Picture
 Todd           | 1               | A Tribe Called Quest: The Video Anthology
 Roberto        | Arce            | Diez aΓ±os juntos. Gala del dΓ©cimo aniversario
                | 3 Doors Down    | 2004 Radio Music Awards
                | 3 Steps Ahead   | Thunderdome: A Decade
 Articolo       | 31              | L'erba proibita
(10 rows)

 count  
--------
 535981
(1 row)

 actorfirstname  | actorsecondname |               first_role_title               | first_role_year 
-----------------+-----------------+----------------------------------------------+-----------------
 Kyle            | Aames           | A Rim with a View 2                          | 2006
 Willie          | Aames           | 20 Greatest Celebreality Moments             | 2006
                 | Aamir (IV)      | Madhosh                                      | 1974
                 | Aamir (V)       | Heroine No.1                                 | 2001
 Mian            | Aamir           | The Girl Without a Song                      | 0000
 Sadiq           | Aamir           | Zinda Bhaag                                  | 2013
 Anders          | Aamodt          | The Recording                                | 2013
 Anders Kristian | Aamodt          | From Another Place                           | 2016
 Kitty           | Aamodt          | Alcohol By Volume                            | 2012
 Kjetil AndrΓ©    | Aamodt          | Bud Greenspan Presents: Torino 2006 Olympics | 2007
 Kristian        | Aamodt          | Kristine Valdresdatter                       | 1930
 Michael G.      | Aamodt          | Biography                                    | 1987
 Thor Michael    | Aamodt          | ...av hensyn til rikets sikkerhet            | 1989
 Tommy           | Aamodt          | Mengaloth                                    | 2005
                 | Aamon           | Geared Up 3                                  | 2013
(15 rows)

 actorfirstname | actorsecondname | roles_count 
----------------+-----------------+-------------
 Johnny         | Gilbert         |        7772
 Alex           | Trebek          |        7737
 Bob            | Barker          |        6950
 Pat            | Sajak           |        6668
 David          | Letterman       |        6474
 Paul           | Shaffer         |        6180
 Johnny         | Olson           |        6116
 Jay            | Leno            |        5640
 Ed             | McMahon         |        5108
 Frank          | Welker          |        5046
(10 rows)

 actorfirstname | actorsecondname 
----------------+-----------------
 Willie         | Aames
 Asger          | Aamund
                | Aari
 Kate           | Aarness
 Daniel         | Aarnio
 Marcus Mathias | Aarnseth
 Tony           | Aaron II
 Ben            | Aaron
 Just           | Aaron
 Matthew        | Aaron
(10 rows)

 actorfirstname | actorsecondname |                                                                   doctor_roles                                                                    
----------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------
                | Aanoosh         | [{"year": "1972", "title": "Shahr-e aftab", "credit": "3", "character name": "Doctor"}]
 Joe            | Aaron           | [{"year": "2017", "title": "See Pap Love", "credit": "4", "character name": "Doctor"}]
 Josh           | Aaron           | [{"year": "0000", "title": "Apnea", "character name": "Doctor Wayne"}]
 Lance          | Aaron           | [{"year": "2013", "title": "The Burden", "character name": "Doctor"}]
 Jerome         | Aarts           | [{"year": "2008", "title": "John Adams", "credit": "11", "episode": "1.3", "series name": "Don't Tread on Me", "character name": "Dutch Doctor"}]
(5 rows)

 actorfirstname | actorsecondname |                                                                                          actor_summary                                                                                          
----------------+-----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Rupert         | Aarons          | {"name": "Rupert Aarons", "first_role": {"year": "1980", "title": "Mystery!", "series name": "David Suchet on the Orient Express", "character name": "Himself"}, "roles_count": 1}
 Shawn          | Aarons          | {"name": "Shawn Aarons", "first_role": {"year": "2008", "title": "Never Back Down", "type1": "uncredited", "character name": "Wide Receiver"}, "roles_count": 1}
 Todd           | Aarons          | {"name": "Todd Aarons", "first_role": {"year": "2010", "title": "Phoebe", "credit": "3", "character name": "Phone Tech #2"}, "roles_count": 1}
 Doron          | Aaronsohn       | {"name": "Doron Aaronsohn", "first_role": {"year": "2009", "title": "1:0", "character name": "Soldier#1"}, "roles_count": 1}
 Alan           | Aaronson        | {"name": "Alan Aaronson", "first_role": {"year": "1958", "title": "The Party Crashers", "type1": "uncredited", "character name": "Ted Nickerson"}, "roles_count": 7}
 Bob            | Aaronson        | {"name": "Bob Aaronson", "first_role": {"year": "1990", "title": "Metamorphosis: The Alien Factor", "type1": "voice", "credit": "13", "character name": "Additional voices"}, "roles_count": 1}
 Brandon        | Aaronson        | {"name": "Brandon Aaronson", "first_role": {"year": "2014", "title": "Unstoppable Love", "credit": "6", "character name": "Band"}, "roles_count": 1}
 Craig          | Aaronson        | {"name": "Craig Aaronson", "first_role": {"year": "2007", "title": "Punk's Not Dead", "credit": "1", "character name": "Himself - Warner Brothers Records"}, "roles_count": 1}
 David          | Aaronson        | {"name": "David Aaronson", "first_role": {"year": "2001", "title": "The Fear", "credit": "2", "character name": "Tom Robinson"}, "roles_count": 1}
 Irving         | Aaronson        | {"name": "Irving Aaronson", "first_role": {"year": "1929", "title": "Aaronson's Commanders", "character name": "Himself"}, "roles_count": 2}
(10 rows)

 actorfirstname | actorsecondname |             role_title             
----------------+-----------------+------------------------------------
 Rupert         | Aarons          | Mystery!
 Shawn          | Aarons          | Never Back Down
 Todd           | Aarons          | Phoebe
 Doron          | Aaronsohn       | 1:0
 Alan           | Aaronson        | The Party Crashers
 Alan           | Aaronson        | The Pied Piper of Hamelin
 Alan           | Aaronson        | Underworld U.S.A.
 Alan           | Aaronson        | The Donna Reed Show
 Alan           | Aaronson        | The Donna Reed Show
 Alan           | Aaronson        | The O. Henry Playhouse
 Alan           | Aaronson        | Westinghouse Desilu Playhouse
 Bob            | Aaronson        | Metamorphosis: The Alien Factor
 Brandon        | Aaronson        | Unstoppable Love
 Craig          | Aaronson        | Punk's Not Dead
 David          | Aaronson        | The Fear
 Irving         | Aaronson        | Aaronson's Commanders
 Irving         | Aaronson        | Irving Aaronson and His Commanders
 Jack           | Aaronson        | The Big Gay Musical
 James          | Aaronson        | Of Plants & Plans
 James          | Aaronson        | The Making of a Superhero Musical
(20 rows)

Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ΠΈΠ΅ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ доступа ΠΊ полю JSONB

Π’ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ ./2-timings Ρ€Π°ΡΠΏΠΎΠ»Π°Π³Π°ΡŽΡ‚ΡΡ Π΄Π²Π° скрипта: 1-timings.sql ΠΈ 2-timings.py.

ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²Π»Π΅Π½Π½Ρ‹Π΅ скрипты Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‚ комплСксноС исслСдованиС влияния Ρ€Π°Π·ΠΌΠ΅Ρ€Π° JSONB-ΠΏΠΎΠ»Π΅ΠΉ Π½Π° ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ доступа ΠΊ Π½ΠΈΠΌ Π² PostgreSQL, Ρ„ΠΎΠΊΡƒΡΠΈΡ€ΡƒΡΡΡŒ Π½Π° Π²Π°ΠΆΠ½ΠΎΠΉ Π³Ρ€Π°Π½ΠΈΡ‡Π½ΠΎΠΉ Ρ‚ΠΎΡ‡ΠΊΠ΅ Π² 2KB (ΠΏΠΎΡ€ΠΎΠ³ TOAST ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ°).

SQL-скрипт (1-timings.sql) - сбор Π΄Π°Π½Π½Ρ‹Ρ…

Запуск скрипта

psql -U postgres -d imdb -f ./2-timings/1-timings.sql | cat

Π¨Π°Π³ 1: ΠŸΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ° тСстовых Π΄Π°Π½Π½Ρ‹Ρ…

CREATE TEMP TABLE jsonb_access_sample AS
WITH small_docs AS (
    -- Π’Ρ‹Π±ΠΎΡ€ΠΊΠ° Π°ΠΊΡ‚Π΅Ρ€ΠΎΠ² с малСньким JSONB (мСньшС 2kB)
    SELECT
        id,
        RolesName,
        pg_column_size(RolesName) AS jsonb_size
    FROM
        actors
    WHERE
        pg_column_size(RolesName) < 2048
    LIMIT 50
),
large_docs AS (
    -- ... ΠΊΠΎΠ΄ ...
  • Боздаётся врСмСнная Ρ‚Π°Π±Π»ΠΈΡ†Π° с Ρ€Π΅ΠΏΡ€Π΅Π·Π΅Π½Ρ‚Π°Ρ‚ΠΈΠ²Π½ΠΎΠΉ Π²Ρ‹Π±ΠΎΡ€ΠΊΠΎΠΉ:
    • 50 записСй Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠΌ мСньшС 2KB (хранятся inline);
    • 50 записСй Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠΌ большС 2KB (ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ TOAST).
  • Ѐункция pg_column_size() опрСдСляСт Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€ Π΄Π°Π½Π½Ρ‹Ρ… JSONB Π² Π±Π°ΠΉΡ‚Π°Ρ….
  • КаТдой записи присваиваСтся ΠΌΠ΅Ρ‚ΠΊΠ° 'inline' ΠΈΠ»ΠΈ 'toasted'.

Π¨Π°Π³ 2: ΠŸΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ° Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ для Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ²

Боздаётся Ρ‚Π°Π±Π»ΠΈΡ†Π° jsonb_access_metrics для хранСния Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² ΠΈΠ·ΠΌΠ΅Ρ€Π΅Π½ΠΈΠΉ:

  • id - ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ записи.
  • jsonb_size - Ρ€Π°Π·ΠΌΠ΅Ρ€ JSONB Π² Π±Π°ΠΉΡ‚Π°Ρ….
  • storage_type - Ρ‚ΠΈΠΏ хранСния (inline/toasted).
  • roles_count - количСство Ρ€ΠΎΠ»Π΅ΠΉ Π² массивС.
  • access_time_ns - ΠΈΠ·ΠΌΠ΅Ρ€Π΅Π½Π½ΠΎΠ΅ врСмя доступа Π² наносСкундах.

Π¨Π°Π³ 3: Ѐункция измСрСния Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ доступа

CREATE OR REPLACE FUNCTION measure_jsonb_access(p_id int, p_iterations int DEFAULT 10)
    RETURNS float
    AS $$
  • Π‘ΠΎΠ·Π΄Π°Ρ‘Ρ‚ PL/pgSQL Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ для высокоточных ΠΈΠ·ΠΌΠ΅Ρ€Π΅Π½ΠΈΠΉ.
  • ВыполняСт Π·Π°Π΄Π°Π½Π½Ρ‹ΠΉ запрос нСсколько Ρ€Π°Π· (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ 10 ΠΈΡ‚Π΅Ρ€Π°Ρ†ΠΈΠΉ) для усрСднСния Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ².
  • Π˜Π·ΠΌΠ΅Ρ€ΡΠ΅Ρ‚ ΠΈΠΌΠ΅Π½Π½ΠΎ врСмя доступа ΠΊ полю year ΠΈΠ· ΠΏΠ΅Ρ€Π²ΠΎΠΉ Ρ€ΠΎΠ»ΠΈ Π°ΠΊΡ‚Ρ‘Ρ€Π°: RolesName->'roles'->0->>'year'.
  • Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ clock_timestamp() для микросСкундной точности ΠΈΠ·ΠΌΠ΅Ρ€Π΅Π½ΠΈΠΉ.
  • Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ срСднСС врСмя доступа Π² наносСкундах.

Π¨Π°Π³ 4: ΠŸΡ€ΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΈΠ·ΠΌΠ΅Ρ€Π΅Π½ΠΈΠΉ

DO $$
DECLARE
    rec RECORD;
    access_time float;
    roles_count int;
BEGIN
    -- Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ΠΈΡ для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ записи
    FOR rec IN
    SELECT
        id,
        jsonb_size,
        storage_type
    FROM
        jsonb_access_sample
    ORDER BY
        jsonb_size LOOP
            -- Π˜Π·ΠΌΠ΅Ρ€ΡΠ΅ΠΌ врСмя доступа
            access_time := measure_jsonb_access(rec.id, 10);
            -- ... ΠΊΠΎΠ΄ ...
  • Π‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π°Π½ΠΎΠ½ΠΈΠΌΠ½ΠΎΠ³ΠΎ Π±Π»ΠΎΠΊΠ° выполняСтся Ρ†ΠΈΠΊΠ» ΠΏΠΎ всСм тСстовым записям.
  • Для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ записи:
    1. Π˜Π·ΠΌΠ΅Ρ€ΡΠ΅Ρ‚ΡΡ врСмя доступа с 10 итСрациями для ΡƒΠΌΠ΅Π½ΡŒΡˆΠ΅Π½ΠΈΡ случайных ΠΊΠΎΠ»Π΅Π±Π°Π½ΠΈΠΉ;
    2. ΠŸΠΎΠ΄ΡΡ‡ΠΈΡ‚Ρ‹Π²Π°Π΅Ρ‚ΡΡ количСство Ρ€ΠΎΠ»Π΅ΠΉ Π°ΠΊΡ‚Ρ‘Ρ€Π°;
    3. Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ ΡΠΎΡ…Ρ€Π°Π½ΡΡŽΡ‚ΡΡ Π² Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊ;
    4. Выводится ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΎΠ½Π½ΠΎΠ΅ сообщСниС ΠΎ прогрСссС с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ RAISE NOTICE.

Π¨Π°Π³ 5: Анализ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² ΠΈ экспорт

  • ВыполняСтся Π°Π³Ρ€Π΅Π³ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ запрос, Π³Ρ€ΡƒΠΏΠΏΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎ Ρ‚ΠΈΠΏΡƒ хранСния:

    SELECT
        storage_type,
        COUNT(*) AS samples,
        ROUND(AVG(jsonb_size)) AS avg_size_bytes,
        -- ... ΠΊΠΎΠ΄ ...
  • Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ Π·Π°ΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ΡΡ Π² CSV-Ρ„Π°ΠΉΠ» Ρ‡Π΅Ρ€Π΅Π· ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ COPY:

    COPY (
      SELECT
          id,
          jsonb_size,
          storage_type,
          roles_count,
          access_time_ns
      FROM
          jsonb_access_metrics
      ORDER BY
          jsonb_size)
      TO '/tmp/jsonb_access_data.csv' WITH CSV HEADER;

Π’Ρ‹Π²ΠΎΠ΄ скрипта

psql:2-timings/1-timings.sql:2: NOTICE:  table "jsonb_access_sample" does not exist, skipping
DROP TABLE
SELECT 100
 total_samples | inline_samples | toasted_samples 
---------------+----------------+-----------------
           100 |             50 |              50
(1 row)

psql:2-timings/1-timings.sql:35: NOTICE:  table "jsonb_access_metrics" does not exist, skipping
DROP TABLE
CREATE TABLE
CREATE FUNCTION
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=7579, Ρ€Π°Π·ΠΌΠ΅Ρ€=75, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=39700.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1651, Ρ€Π°Π·ΠΌΠ΅Ρ€=75, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=4600.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1642, Ρ€Π°Π·ΠΌΠ΅Ρ€=76, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=3600.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1640, Ρ€Π°Π·ΠΌΠ΅Ρ€=90, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=3600.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1612, Ρ€Π°Π·ΠΌΠ΅Ρ€=96, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=3600.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1647, Ρ€Π°Π·ΠΌΠ΅Ρ€=102, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=3500.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1632, Ρ€Π°Π·ΠΌΠ΅Ρ€=107, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=3800.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1653, Ρ€Π°Π·ΠΌΠ΅Ρ€=108, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=3800.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1619, Ρ€Π°Π·ΠΌΠ΅Ρ€=110, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=3700.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1660, Ρ€Π°Π·ΠΌΠ΅Ρ€=110, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=3600.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1630, Ρ€Π°Π·ΠΌΠ΅Ρ€=113, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=3700.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1635, Ρ€Π°Π·ΠΌΠ΅Ρ€=115, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=3800.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1641, Ρ€Π°Π·ΠΌΠ΅Ρ€=116, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=3900.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1611, Ρ€Π°Π·ΠΌΠ΅Ρ€=118, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=3800.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1617, Ρ€Π°Π·ΠΌΠ΅Ρ€=119, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=4000.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1615, Ρ€Π°Π·ΠΌΠ΅Ρ€=119, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=3900.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1648, Ρ€Π°Π·ΠΌΠ΅Ρ€=119, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=3600.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1639, Ρ€Π°Π·ΠΌΠ΅Ρ€=123, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=4100.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1621, Ρ€Π°Π·ΠΌΠ΅Ρ€=125, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=4400.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1654, Ρ€Π°Π·ΠΌΠ΅Ρ€=125, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=4300.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1628, Ρ€Π°Π·ΠΌΠ΅Ρ€=125, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=4300.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1633, Ρ€Π°Π·ΠΌΠ΅Ρ€=126, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=4200.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1652, Ρ€Π°Π·ΠΌΠ΅Ρ€=127, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=4500.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1627, Ρ€Π°Π·ΠΌΠ΅Ρ€=131, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=4500.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1622, Ρ€Π°Π·ΠΌΠ΅Ρ€=131, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=5200.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1655, Ρ€Π°Π·ΠΌΠ΅Ρ€=132, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=4400.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1650, Ρ€Π°Π·ΠΌΠ΅Ρ€=133, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=5100.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1623, Ρ€Π°Π·ΠΌΠ΅Ρ€=134, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=5100.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1610, Ρ€Π°Π·ΠΌΠ΅Ρ€=138, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=4500.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1616, Ρ€Π°Π·ΠΌΠ΅Ρ€=150, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=6200.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1609, Ρ€Π°Π·ΠΌΠ΅Ρ€=155, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=7700.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1625, Ρ€Π°Π·ΠΌΠ΅Ρ€=155, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=7600.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1643, Ρ€Π°Π·ΠΌΠ΅Ρ€=163, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=7900.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1614, Ρ€Π°Π·ΠΌΠ΅Ρ€=169, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=7400.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1634, Ρ€Π°Π·ΠΌΠ΅Ρ€=173, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=2, врСмя=7900.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1624, Ρ€Π°Π·ΠΌΠ΅Ρ€=175, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=2, врСмя=7900.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1646, Ρ€Π°Π·ΠΌΠ΅Ρ€=182, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=2, врСмя=8400.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1649, Ρ€Π°Π·ΠΌΠ΅Ρ€=202, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=2, врСмя=4900.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1631, Ρ€Π°Π·ΠΌΠ΅Ρ€=203, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=2, врСмя=5100.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1656, Ρ€Π°Π·ΠΌΠ΅Ρ€=205, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=1, врСмя=6500.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1620, Ρ€Π°Π·ΠΌΠ΅Ρ€=205, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=2, врСмя=5300.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1618, Ρ€Π°Π·ΠΌΠ΅Ρ€=231, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=2, врСмя=5300.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1636, Ρ€Π°Π·ΠΌΠ΅Ρ€=326, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=3, врСмя=5400.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1645, Ρ€Π°Π·ΠΌΠ΅Ρ€=381, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=3, врСмя=6100.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1629, Ρ€Π°Π·ΠΌΠ΅Ρ€=681, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=7, врСмя=6200.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1613, Ρ€Π°Π·ΠΌΠ΅Ρ€=892, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=7, врСмя=6000.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1637, Ρ€Π°Π·ΠΌΠ΅Ρ€=894, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=8, врСмя=5900.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1644, Ρ€Π°Π·ΠΌΠ΅Ρ€=933, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=7, врСмя=5900.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1638, Ρ€Π°Π·ΠΌΠ΅Ρ€=1077, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=19, врСмя=7700.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1626, Ρ€Π°Π·ΠΌΠ΅Ρ€=1489, Ρ‚ΠΈΠΏ=inline, Ρ€ΠΎΠ»ΠΈ=12, врСмя=6100.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=2395, Ρ€Π°Π·ΠΌΠ΅Ρ€=2116, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=53, врСмя=22500.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=2362, Ρ€Π°Π·ΠΌΠ΅Ρ€=2132, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=39, врСмя=17100.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=2632, Ρ€Π°Π·ΠΌΠ΅Ρ€=2139, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=41, врСмя=11700.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=4567, Ρ€Π°Π·ΠΌΠ΅Ρ€=2222, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=61, врСмя=15300.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=3200, Ρ€Π°Π·ΠΌΠ΅Ρ€=2246, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=55, врСмя=20500.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=2232, Ρ€Π°Π·ΠΌΠ΅Ρ€=2249, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=77, врСмя=11900.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=3221, Ρ€Π°Π·ΠΌΠ΅Ρ€=2264, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=38, врСмя=17200.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=3680, Ρ€Π°Π·ΠΌΠ΅Ρ€=2270, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=55, врСмя=18900.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=4064, Ρ€Π°Π·ΠΌΠ΅Ρ€=2279, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=70, врСмя=21500.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=4627, Ρ€Π°Π·ΠΌΠ΅Ρ€=2320, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=39, врСмя=13100.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=4928, Ρ€Π°Π·ΠΌΠ΅Ρ€=2339, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=70, врСмя=12900.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=3720, Ρ€Π°Π·ΠΌΠ΅Ρ€=2371, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=62, врСмя=14600.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=3509, Ρ€Π°Π·ΠΌΠ΅Ρ€=2410, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=400, врСмя=18300.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=4441, Ρ€Π°Π·ΠΌΠ΅Ρ€=2413, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=45, врСмя=14800.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1865, Ρ€Π°Π·ΠΌΠ΅Ρ€=2456, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=95, врСмя=19500.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=2005, Ρ€Π°Π·ΠΌΠ΅Ρ€=2673, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=265, врСмя=20400.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=2941, Ρ€Π°Π·ΠΌΠ΅Ρ€=2802, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=71, врСмя=13400.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=2043, Ρ€Π°Π·ΠΌΠ΅Ρ€=2805, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=67, врСмя=13500.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=3414, Ρ€Π°Π·ΠΌΠ΅Ρ€=2871, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=224, врСмя=23500.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=2572, Ρ€Π°Π·ΠΌΠ΅Ρ€=2951, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=102, врСмя=20200.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=2488, Ρ€Π°Π·ΠΌΠ΅Ρ€=2988, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=57, врСмя=25400.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=4662, Ρ€Π°Π·ΠΌΠ΅Ρ€=2994, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=65, врСмя=24300.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=3311, Ρ€Π°Π·ΠΌΠ΅Ρ€=3015, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=60, врСмя=22100.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=3178, Ρ€Π°Π·ΠΌΠ΅Ρ€=3091, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=72, врСмя=27600.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=1729, Ρ€Π°Π·ΠΌΠ΅Ρ€=3171, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=73, врСмя=58800.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=4775, Ρ€Π°Π·ΠΌΠ΅Ρ€=3426, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=85, врСмя=85600.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=4611, Ρ€Π°Π·ΠΌΠ΅Ρ€=3479, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=76, врСмя=25800.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=2698, Ρ€Π°Π·ΠΌΠ΅Ρ€=3559, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=145, врСмя=35000.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=3521, Ρ€Π°Π·ΠΌΠ΅Ρ€=3575, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=101, врСмя=26700.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=3009, Ρ€Π°Π·ΠΌΠ΅Ρ€=3659, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=93, врСмя=26900.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=2328, Ρ€Π°Π·ΠΌΠ΅Ρ€=3846, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=266, врСмя=29400.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=2610, Ρ€Π°Π·ΠΌΠ΅Ρ€=4259, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=154, врСмя=42600.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=2671, Ρ€Π°Π·ΠΌΠ΅Ρ€=4313, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=102, врСмя=30400.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=3252, Ρ€Π°Π·ΠΌΠ΅Ρ€=4344, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=105, врСмя=23800.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=3062, Ρ€Π°Π·ΠΌΠ΅Ρ€=4586, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=96, врСмя=24200.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=2336, Ρ€Π°Π·ΠΌΠ΅Ρ€=4674, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=99, врСмя=27000.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=4769, Ρ€Π°Π·ΠΌΠ΅Ρ€=4682, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=127, врСмя=24400.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=2447, Ρ€Π°Π·ΠΌΠ΅Ρ€=4970, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=130, врСмя=25800.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=2387, Ρ€Π°Π·ΠΌΠ΅Ρ€=6449, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=602, врСмя=67800.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=3181, Ρ€Π°Π·ΠΌΠ΅Ρ€=6974, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=184, врСмя=31100.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=4913, Ρ€Π°Π·ΠΌΠ΅Ρ€=7516, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=286, врСмя=29100.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=3124, Ρ€Π°Π·ΠΌΠ΅Ρ€=7934, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=319, врСмя=26400.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=3310, Ρ€Π°Π·ΠΌΠ΅Ρ€=9063, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=184, врСмя=42500.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=2545, Ρ€Π°Π·ΠΌΠ΅Ρ€=9240, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=539, врСмя=86400.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=4891, Ρ€Π°Π·ΠΌΠ΅Ρ€=9381, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=210, врСмя=51100.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=4404, Ρ€Π°Π·ΠΌΠ΅Ρ€=11201, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=270, врСмя=38300.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=3456, Ρ€Π°Π·ΠΌΠ΅Ρ€=11362, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=922, врСмя=125100.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=3396, Ρ€Π°Π·ΠΌΠ΅Ρ€=15441, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=448, врСмя=92600.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=2230, Ρ€Π°Π·ΠΌΠ΅Ρ€=21679, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=504, врСмя=159100.00 нс
psql:2-timings/1-timings.sql:99: NOTICE:  Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ ID=3010, Ρ€Π°Π·ΠΌΠ΅Ρ€=29281, Ρ‚ΠΈΠΏ=toasted, Ρ€ΠΎΠ»ΠΈ=928, врСмя=197700.00 нс
DO
 storage_type | samples | avg_size_bytes | avg_roles | avg_time_ns | min_time_ns | max_time_ns 
--------------+---------+----------------+-----------+-------------+-------------+-------------
 inline       |      50 |            247 |         2 |        5844 |        3500 |       39700
 toasted      |      50 |           5250 |       185 |       37476 |       11700 |      197700
(2 rows)

  id  | jsonb_size | storage_type | roles_count | access_time_ns 
------+------------+--------------+-------------+----------------
 7579 |         75 | inline       |           1 |          39700
 1651 |         75 | inline       |           1 |           4600
 1642 |         76 | inline       |           1 |           3600
 1640 |         90 | inline       |           1 |           3600
 1612 |         96 | inline       |           1 |           3600
 1647 |        102 | inline       |           1 |           3500
 1632 |        107 | inline       |           1 |           3800
 1653 |        108 | inline       |           1 |           3800
 1619 |        110 | inline       |           1 |           3700
 1660 |        110 | inline       |           1 |           3600
 1630 |        113 | inline       |           1 |           3700
 1635 |        115 | inline       |           1 |           3800
 1641 |        116 | inline       |           1 |           3900
 1611 |        118 | inline       |           1 |           3800
 1617 |        119 | inline       |           1 |           4000
 1615 |        119 | inline       |           1 |           3900
 1648 |        119 | inline       |           1 |           3600
 1639 |        123 | inline       |           1 |           4100
 1621 |        125 | inline       |           1 |           4400
 1654 |        125 | inline       |           1 |           4300
 1628 |        125 | inline       |           1 |           4300
 1633 |        126 | inline       |           1 |           4200
 1652 |        127 | inline       |           1 |           4500
 1627 |        131 | inline       |           1 |           4500
 1622 |        131 | inline       |           1 |           5200
 1655 |        132 | inline       |           1 |           4400
 1650 |        133 | inline       |           1 |           5100
 1623 |        134 | inline       |           1 |           5100
 1610 |        138 | inline       |           1 |           4500
 1616 |        150 | inline       |           1 |           6200
 1609 |        155 | inline       |           1 |           7700
 1625 |        155 | inline       |           1 |           7600
 1643 |        163 | inline       |           1 |           7900
 1614 |        169 | inline       |           1 |           7400
 1634 |        173 | inline       |           2 |           7900
 1624 |        175 | inline       |           2 |           7900
 1646 |        182 | inline       |           2 |           8400
 1649 |        202 | inline       |           2 |           4900
 1631 |        203 | inline       |           2 |           5100
 1656 |        205 | inline       |           1 |           6500
 1620 |        205 | inline       |           2 |           5300
 1618 |        231 | inline       |           2 |           5300
 1636 |        326 | inline       |           3 |           5400
 1645 |        381 | inline       |           3 |           6100
 1629 |        681 | inline       |           7 |           6200
 1613 |        892 | inline       |           7 |           6000
 1637 |        894 | inline       |           8 |           5900
 1644 |        933 | inline       |           7 |           5900
 1638 |       1077 | inline       |          19 |           7700
 1626 |       1489 | inline       |          12 |           6100
 2395 |       2116 | toasted      |          53 |          22500
 2362 |       2132 | toasted      |          39 |          17100
 2632 |       2139 | toasted      |          41 |          11700
 4567 |       2222 | toasted      |          61 |          15300
 3200 |       2246 | toasted      |          55 |          20500
 2232 |       2249 | toasted      |          77 |          11900
 3221 |       2264 | toasted      |          38 |          17200
 3680 |       2270 | toasted      |          55 |          18900
 4064 |       2279 | toasted      |          70 |          21500
 4627 |       2320 | toasted      |          39 |          13100
 4928 |       2339 | toasted      |          70 |          12900
 3720 |       2371 | toasted      |          62 |          14600
 3509 |       2410 | toasted      |         400 |          18300
 4441 |       2413 | toasted      |          45 |          14800
 1865 |       2456 | toasted      |          95 |          19500
 2005 |       2673 | toasted      |         265 |          20400
 2941 |       2802 | toasted      |          71 |          13400
 2043 |       2805 | toasted      |          67 |          13500
 3414 |       2871 | toasted      |         224 |          23500
 2572 |       2951 | toasted      |         102 |          20200
 2488 |       2988 | toasted      |          57 |          25400
 4662 |       2994 | toasted      |          65 |          24300
 3311 |       3015 | toasted      |          60 |          22100
 3178 |       3091 | toasted      |          72 |          27600
 1729 |       3171 | toasted      |          73 |          58800
 4775 |       3426 | toasted      |          85 |          85600
 4611 |       3479 | toasted      |          76 |          25800
 2698 |       3559 | toasted      |         145 |          35000
 3521 |       3575 | toasted      |         101 |          26700
 3009 |       3659 | toasted      |          93 |          26900
 2328 |       3846 | toasted      |         266 |          29400
 2610 |       4259 | toasted      |         154 |          42600
 2671 |       4313 | toasted      |         102 |          30400
 3252 |       4344 | toasted      |         105 |          23800
 3062 |       4586 | toasted      |          96 |          24200
 2336 |       4674 | toasted      |          99 |          27000
 4769 |       4682 | toasted      |         127 |          24400
 2447 |       4970 | toasted      |         130 |          25800
 2387 |       6449 | toasted      |         602 |          67800
 3181 |       6974 | toasted      |         184 |          31100
 4913 |       7516 | toasted      |         286 |          29100
 3124 |       7934 | toasted      |         319 |          26400
 3310 |       9063 | toasted      |         184 |          42500
 2545 |       9240 | toasted      |         539 |          86400
 4891 |       9381 | toasted      |         210 |          51100
 4404 |      11201 | toasted      |         270 |          38300
 3456 |      11362 | toasted      |         922 |         125100
 3396 |      15441 | toasted      |         448 |          92600
 2230 |      21679 | toasted      |         504 |         159100
 3010 |      29281 | toasted      |         928 |         197700
(100 rows)

COPY 100

Python-скрипт (2-timings.py) - визуализация ΠΈ интСрпрСтация

Запуск скрипта

python ./2-timings/2-timings.py

Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° ΠΈ ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ° Π΄Π°Π½Π½Ρ‹Ρ…

# Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ Π΄Π°Π½Π½Ρ‹Π΅
df = pd.read_csv(file_path)
print(f"Π—Π°Π³Ρ€ΡƒΠΆΠ΅Π½ΠΎ {len(df)} записСй")

# РаздСляСм Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎ Ρ‚ΠΈΠΏΡƒ хранСния
inline_data = df[df["storage_type"] == "inline"]
toasted_data = df[df["storage_type"] == "toasted"]
  • Π‘ΠΊΡ€ΠΈΠΏΡ‚ Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ·ΠΌΠ΅Ρ€Π΅Π½ΠΈΠΉ ΠΈΠ· CSV-Ρ„Π°ΠΉΠ»Π°.
  • РаздСляСт Π΄Π°Π½Π½Ρ‹Π΅ Π½Π° Π΄Π²Π΅ Π³Ρ€ΡƒΠΏΠΏΡ‹: встроСнныС (<2KB) ΠΈ TOAST (>2KB).

ΠŸΠΎΡΡ‚Ρ€ΠΎΠ΅Π½ΠΈΠ΅ Π΄ΠΈΠ°Π³Ρ€Π°ΠΌΠΌΡ‹ рассСяния

# Π‘Ρ‚Ρ€ΠΎΠΈΠΌ Ρ‚ΠΎΡ‡ΠΊΠΈ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° хранСния
plt.scatter(
    inline_data["jsonb_size"],
    inline_data["access_time_ns"],
    color="blue",
    alpha=0.7,
    label="ВстроСнныС (<2kB)",
)
  • На Π΄ΠΈΠ°Π³Ρ€Π°ΠΌΠΌΡƒ наносятся Ρ‚ΠΎΡ‡ΠΊΠΈ с ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Π°ΠΌΠΈ:
    • X: Ρ€Π°Π·ΠΌΠ΅Ρ€ JSONB (Π² Π±Π°ΠΉΡ‚Π°Ρ…).
    • Y: врСмя доступа (Π² наносСкундах).
  • Π Π°Π·Π½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ хранСния Π²Ρ‹Π΄Π΅Π»Π΅Π½Ρ‹ Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ Ρ†Π²Π΅Ρ‚Π°ΠΌΠΈ (синий - inline, красный - TOAST).

Расчёт Π»ΠΈΠ½ΠΈΠΉ Ρ‚Ρ€Π΅Π½Π΄Π°

# ДобавляСм Π»ΠΈΠ½ΠΈΠΈ Ρ‚Ρ€Π΅Π½Π΄Π° для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Π³Ρ€ΡƒΠΏΠΏΡ‹
if len(inline_data) > 1 and inline_data["jsonb_size"].nunique() > 1:
    slope, intercept, r_value, _, _ = linregress(
        inline_data["jsonb_size"], inline_data["access_time_ns"]
    )
  • Для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Π³Ρ€ΡƒΠΏΠΏΡ‹ Π΄Π°Π½Π½Ρ‹Ρ… рассчитываСтся линия Ρ‚Ρ€Π΅Π½Π΄Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π»ΠΈΠ½Π΅ΠΉΠ½ΠΎΠΉ рСгрСссии.
  • ВычисляСтся коэффициСнт Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Ρ†ΠΈΠΈ RΒ² для ΠΎΡ†Π΅Π½ΠΊΠΈ силы Π»ΠΈΠ½Π΅ΠΉΠ½ΠΎΠΉ зависимости.
  • На Π³Ρ€Π°Ρ„ΠΈΠΊ Π΄ΠΎΠ±Π°Π²Π»ΡΡŽΡ‚ΡΡ Π»ΠΈΠ½ΠΈΠΈ Ρ‚Ρ€Π΅Π½Π΄Π° с ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌΠΈ ΠΌΠ΅Ρ‚ΠΊΠ°ΠΌΠΈ.

Визуализация "ΡΡ‚ΡƒΠΏΠ΅Π½ΡŒΠΊΠΈ" ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ

# ДобавляСм линию Π³Ρ€Π°Π½ΠΈΡ†Ρ‹ TOAST
plt.axvline(
    x=2048, color="green", linestyle="--", linewidth=2, label="TOAST Π³Ρ€Π°Π½ΠΈΡ†Π° (2kB)"
)

# ДобавляСм срСдниС Π»ΠΈΠ½ΠΈΠΈ для Π²ΠΈΠ·ΡƒΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ "ΡΡ‚ΡƒΠΏΠ΅Π½ΡŒΠΊΠΈ"
if len(inline_data) > 0:
    avg_inline = inline_data["access_time_ns"].mean()
    plt.axhline(y=avg_inline, ...)
  • Π’Π΅Ρ€Ρ‚ΠΈΠΊΠ°Π»ΡŒΠ½Π°Ρ зСлёная линия ΠΎΡ‚ΠΌΠ΅Ρ‡Π°Π΅Ρ‚ Π³Ρ€Π°Π½ΠΈΡ†Ρƒ ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ‚ΠΈΠΏΠ°ΠΌΠΈ хранСния (2KB).
  • Π“ΠΎΡ€ΠΈΠ·ΠΎΠ½Ρ‚Π°Π»ΡŒΠ½Ρ‹Π΅ Π»ΠΈΠ½ΠΈΠΈ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ срСдниС значСния Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ доступа для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°.

Π’Ρ‹Π²ΠΎΠ΄ статистичСских Π΄Π°Π½Π½Ρ‹Ρ…

print("\n=== БВАВИБВИКА ПО Π“Π Π£ΠŸΠŸΠΠœ ===")
for name, group in [("ВстроСнныС (<2kB)", inline_data), ("TOAST (>2kB)", toasted_data)]:
    print(f"\n{name}:")
    print(f"ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ записСй: {len(group)}")
    ...
  • Π‘ΠΊΡ€ΠΈΠΏΡ‚ Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΡƒΡŽ статистику ΠΏΠΎ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Π³Ρ€ΡƒΠΏΠΏΠ΅ Π΄Π°Π½Π½Ρ‹Ρ…:
    • Π‘Ρ€Π΅Π΄Π½ΠΈΠΉ/ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ/ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹;
    • Π‘Ρ€Π΅Π΄Π½Π΅Π΅ врСмя доступа;
    • Π‘ΠΎΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΠ΅ врСмя/Ρ€Π°Π·ΠΌΠ΅Ρ€ (нс/Π±Π°ΠΉΡ‚).

Π’Ρ‹Π²ΠΎΠ΄ скрипта

Π—Π°Π³Ρ€ΡƒΠΆΠ΅Π½ΠΎ 100 записСй
ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ записСй inline: 50
ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ записСй toasted: 50
Π“Ρ€Π°Ρ„ΠΈΠΊ сохранСн: jsonb_access_time.png

=== БВАВИБВИКА ПО Π“Π Π£ΠŸΠŸΠΠœ ===

ВстроСнныС (<2kB):
ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ записСй: 50
Π‘Ρ€Π΅Π΄Π½ΠΈΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€: 247.2 Π±Π°ΠΉΡ‚
ΠœΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€: 75 Π±Π°ΠΉΡ‚
ΠœΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€: 1489 Π±Π°ΠΉΡ‚
Π£Π½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹Ρ… Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠ²: 41
Π‘Ρ€Π΅Π΄Π½Π΅Π΅ врСмя доступа: 5844.00 нс
Π‘ΠΎΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΠ΅ врСмя/Ρ€Π°Π·ΠΌΠ΅Ρ€: 23.6427 нс/Π±Π°ΠΉΡ‚

TOAST (>2kB):
ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ записСй: 50
Π‘Ρ€Π΅Π΄Π½ΠΈΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€: 5249.6 Π±Π°ΠΉΡ‚
ΠœΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€: 2116 Π±Π°ΠΉΡ‚
ΠœΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€: 29281 Π±Π°ΠΉΡ‚
Π£Π½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹Ρ… Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠ²: 50
Π‘Ρ€Π΅Π΄Π½Π΅Π΅ врСмя доступа: 37476.00 нс
Π‘ΠΎΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΠ΅ врСмя/Ρ€Π°Π·ΠΌΠ΅Ρ€: 7.1388 нс/Π±Π°ΠΉΡ‚

ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌΡ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ ΠΈ ΠΈΡ… интСрпрСтация

Π“Ρ€Π°Ρ„ΠΈΠΊ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ доступа ΠΊ JSONB-Π΄Π°Π½Π½Ρ‹ΠΌ

Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ выполнСния скрипта гСнСрируСтся Π³Ρ€Π°Ρ„ΠΈΠΊ, ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°ΡŽΡ‰ΠΈΠΉ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ доступа ΠΊ JSONB-Π΄Π°Π½Π½Ρ‹ΠΌ ΠΎΡ‚ ΠΈΡ… Ρ€Π°Π·ΠΌΠ΅Ρ€Π°:

Π“Ρ€Π°Ρ„ΠΈΠΊ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ доступа ΠΊ JSONB-Π΄Π°Π½Π½Ρ‹ΠΌ

Π’Ρ‹Π²ΠΎΠ΄Ρ‹

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ ΠΏΡ€ΠΎΠ²Π΅Π΄Ρ‘Π½Π½Ρ‹Ρ… ΠΈΠ·ΠΌΠ΅Ρ€Π΅Π½ΠΈΠΉ наглядно Π΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€ΠΈΡ€ΡƒΡŽΡ‚ влияниС ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° TOAST Π½Π° ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ доступа ΠΊ JSONB-Π΄Π°Π½Π½Ρ‹ΠΌ Π² PostgreSQL:

  1. Явная "ΡΡ‚ΡƒΠΏΠ΅Π½ΡŒΠΊΠ°" Π² ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Π½Π° Π³Ρ€Π°Π½ΠΈΡ†Π΅ 2KB:

    • Для Π΄Π°Π½Π½Ρ‹Ρ… мСньшС 2KB (inline Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅): срСднСС врСмя доступа составляСт 5844 нс;
    • Для Π΄Π°Π½Π½Ρ‹Ρ… большС 2KB (TOAST Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅): срСднСС врСмя доступа составляСт 37476 нс;
    • Π Π°Π·Π½ΠΈΡ†Π° составляСт ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ 6.4 Ρ€Π°Π·Π°, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π°Π΅Ρ‚ тСорСтичСскоС ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΎ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΌ влиянии ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° TOAST Π½Π° ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ доступа.
  2. Π₯Π°Ρ€Π°ΠΊΡ‚Π΅Ρ€ зависимости врСмя/Ρ€Π°Π·ΠΌΠ΅Ρ€ различаСтся для Ρ€Π°Π·Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² хранСния:

    • Для inline Π΄Π°Π½Π½Ρ‹Ρ… Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠΌ ΠΈ Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ доступа ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ слабая;
    • Для TOAST Π΄Π°Π½Π½Ρ‹Ρ… Π½Π°Π±Π»ΡŽΠ΄Π°Π΅Ρ‚ΡΡ Π±ΠΎΠ»Π΅Π΅ выраТСнная линСйная Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ, особСнно Π½Π° Π±ΠΎΠ»ΡŒΡˆΠΈΡ… ΠΎΠ±ΡŠΡ‘ΠΌΠ°Ρ… (>10KB).
  3. Π”ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Ρ‹ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ доступа:

    • Inline: ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌ 3500 нс, максимум 39700 нс (выброс для ID=7579);
    • TOAST: ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌ 11700 нс, максимум 197700 нс (для самого большого ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° 29281 Π±Π°ΠΉΡ‚).
  4. ΠŸΠ°Ρ€Π°Π΄ΠΎΠΊΡ эффСктивности:

    • НСсмотря Π½Π° Π±ΠΎΠ»Π΅Π΅ высокоС Π°Π±ΡΠΎΠ»ΡŽΡ‚Π½ΠΎΠ΅ врСмя доступа, TOAST Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ дСмонстрируСт Π»ΡƒΡ‡ΡˆΠ΅Π΅ ΡΠΎΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΠ΅ врСмя/Ρ€Π°Π·ΠΌΠ΅Ρ€: 7.14 нс/Π±Π°ΠΉΡ‚ ΠΏΡ€ΠΎΡ‚ΠΈΠ² 23.64 нс/Π±Π°ΠΉΡ‚ для inline хранСния;
    • Π­Ρ‚ΠΎ ΠΎΠ±ΡŠΡΡΠ½ΡΠ΅Ρ‚ΡΡ Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Π½Π°ΠΊΠ»Π°Π΄Π½Ρ‹Π΅ расходы Π½Π° Π΄Π΅ΠΊΠΎΠΌΠΏΡ€Π΅ΡΡΠΈΡŽ TOAST ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Ρ€Π°ΡΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ΡΡ Π½Π° больший ΠΎΠ±ΡŠΡ‘ΠΌ Π΄Π°Π½Π½Ρ‹Ρ….
  5. ΠšΠΎΡ€Ρ€Π΅Π»ΡΡ†ΠΈΡ с количСством Ρ€ΠΎΠ»Π΅ΠΉ:

    • Π‘Ρ€Π΅Π΄Π½ΠΈΠ΅ характСристики inline хранСния: 247 Π±Π°ΠΉΡ‚ Π½Π° 2 Ρ€ΠΎΠ»ΠΈ;
    • Π‘Ρ€Π΅Π΄Π½ΠΈΠ΅ характСристики TOAST хранСния: 5250 Π±Π°ΠΉΡ‚ Π½Π° 185 Ρ€ΠΎΠ»Π΅ΠΉ;
    • ΠΠ°Π±Π»ΡŽΠ΄Π°Π΅Ρ‚ΡΡ Π·Π°ΠΊΠΎΠ½ΠΎΠΌΠ΅Ρ€Π½ΠΎΡΡ‚ΡŒ: врСмя доступа растёт с ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΠ΅ΠΌ количСства Ρ€ΠΎΠ»Π΅ΠΉ, особСнно для TOAST Π΄Π°Π½Π½Ρ‹Ρ….
  6. Выбросы Π² измСрСниях:

    • Для inline Π΄Π°Π½Π½Ρ‹Ρ… Π·Π°ΠΌΠ΅Ρ‚Π΅Π½ ΠΎΠ΄ΠΈΠ½ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ выброс (ID=7579, 39700 нс);
    • Для TOAST Π΄Π°Π½Π½Ρ‹Ρ… нСсколько выбросов Π½Π° Π±ΠΎΠ»ΡŒΡˆΠΈΡ… ΠΎΠ±ΡŠΡ‘ΠΌΠ°Ρ…, Ρ‡Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ связано с ΠΏΠΎΠ²Ρ‹ΡˆΠ΅Π½Π½ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΎΠΉ Π½Π° систСму ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ.

Π­Ρ‚ΠΈ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π°ΡŽΡ‚ Π³ΠΈΠΏΠΎΡ‚Π΅Π·Ρƒ ΠΎ Π½Π°Π»ΠΈΡ‡ΠΈΠΈ "ΡΡ‚ΡƒΠΏΠ΅Π½ΡŒΠΊΠΈ" Π² ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄Π΅ Ρ‡Π΅Ρ€Π΅Π· ΠΏΠΎΡ€ΠΎΠ³ TOAST (2KB), Π° Ρ‚Π°ΠΊΠΆΠ΅ Π΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€ΠΈΡ€ΡƒΡŽΡ‚ ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ Π»ΠΈΠ½Π΅ΠΉΠ½ΡƒΡŽ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ для Π±ΠΎΠ»ΡŒΡˆΠΈΡ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π΄Π°Π½Π½Ρ‹Ρ….

Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΠΈ ΠΏΠΎ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с большими JSONB-Π΄Π°Π½Π½Ρ‹ΠΌΠΈ

  1. Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ…:

    • Нормализация ΠΊΡ€ΠΈΡ‚ΠΈΡ‡Π½Ρ‹Ρ… ΠΏΠΎΠ»Π΅ΠΉ: вынСситС часто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ ΠΈΠ»ΠΈ ΠΊΡ€ΠΈΡ‚ΠΈΡ‡Π½Ρ‹Π΅ для ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ поля ΠΈΠ· JSONB Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ столбцы Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹;
    • ДСкомпозиция Π±ΠΎΠ»ΡŒΡˆΠΈΡ… Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ²: раздСляйтС большиС JSONB-ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π½Π° логичСскиС части, особСнно Ссли Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ°Π΅Ρ‚ 2KB (ΠΏΠΎΡ€ΠΎΠ³ TOAST).
    -- ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΉ структуры
    CREATE TABLE actors_optimized (
        id integer PRIMARY KEY,
        actor_first_name varchar,
        actor_second_name varchar,
        first_role_year integer,  -- ВынСсСнноС ΠΏΠΎΠ»Π΅ для быстрого доступа
        roles_count integer,      -- Π”Π΅Π½ΠΎΡ€ΠΌΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ счСтчик
        roles_data jsonb          -- ΠžΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ ΠΎ ролях
    );
  2. ЭффСктивная индСксация:

    • Π‘ΠΏΠ΅Ρ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ индСксы: создавайтС индСксы для ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹Ρ… ΠΏΡƒΡ‚Π΅ΠΉ JSON, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ часто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Π² условиях поиска;
    • ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ GIN-индСксы: ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ Ρ‚ΠΈΠΏ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° для индСксации (jsonb_ops ΠΈΠ»ΠΈ jsonb_path_ops);
    • ЧастичныС индСксы: для Π±ΠΎΠ»ΡŒΡˆΠΈΡ… Ρ‚Π°Π±Π»ΠΈΡ† примСняйтС индСксы Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊ Ρ€Π΅Π»Π΅Π²Π°Π½Ρ‚Π½Ρ‹ΠΌ записям:
    -- ИндСкс для часто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠ³ΠΎ поля
    CREATE INDEX idx_first_role_year ON actors ((RolesName->'roles'->0->>'year'));
    
    -- ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ GIN-индСкс для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ вхоТдСния (@>)
    CREATE INDEX idx_jsonb_path_ops ON actors USING GIN (RolesName jsonb_path_ops);
  3. ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡ запросов:

    • Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ JSONPath: ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡ΠΈΡ‚Π°ΠΉΡ‚Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ JSONPath вмСсто ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ примСнСния ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² -> ΠΈ ->> для слоТных условий;
    • ΠœΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Π΅ прСдставлСния: ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ вычисляйтС часто Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌΡ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ для слоТных запросов:
    -- Π­Ρ„Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½Ρ‹ΠΉ запрос с использованиСм JSONPath
    SELECT * FROM actors
    WHERE jsonb_path_exists(RolesName, '$.roles[*] ? (@.year > "2010" && @.credit == "1")');

Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ΠΈΠ΅ влияния ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΉ Π½Π° JSONB с Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ Ρ€Π°Π·ΠΌΠ΅Ρ€Π°ΠΌΠΈ Π΄Π°Π½Π½Ρ‹Ρ…

ΠžΠ±Ρ‰Π΅Π΅ описаниС ΠΈ Ρ†Π΅Π»ΡŒ скрипта

Π‘ΠΊΡ€ΠΈΠΏΡ‚ update-year.sql ΠΏΡ€ΠΎΠ²ΠΎΠ΄ΠΈΡ‚ экспСримСнт для сравнСния влияния обновлСния JSONB-поля Π½Π° объСм Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… Π² зависимости ΠΎΡ‚ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° Π΄Π°Π½Π½Ρ‹Ρ…. Основная Π·Π°Π΄Π°Ρ‡Π° - наглядно ΠΏΡ€ΠΎΠ΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π°Π·Π½ΠΈΡ†Ρƒ Π² ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠΈ PostgreSQL ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с Π΄Π°Π½Π½Ρ‹ΠΌΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ хранятся нСпосрСдствСнно Π² строкС Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ (inline) ΠΈ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠΌΠΈ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ TOAST (The Oversized-Attribute Storage Technique).

Запуск скрипта

Запустим Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Ρ… запросов ΠΈΠ· Ρ„Π°ΠΉΠ»Π° ./3-update-year/update-year.sql Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΠ² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ Π² Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π΅:

psql -U postgres -d imdb -f ./3-update-year/update-year.sql | cat

ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Ρ‹ΠΉ Ρ€Π°Π·Π±ΠΎΡ€ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² скрипта

1. Ѐункция для измСрСния Ρ€Π°Π·ΠΌΠ΅Ρ€Π° Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹

CREATE OR REPLACE FUNCTION get_table_size(p_table text)
    RETURNS TABLE(
        table_size bigint,
        toast_size bigint,
        total_size bigint
    )
    AS $$

Π­Ρ‚Π° функция ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ систСмныС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ PostgreSQL для получСния Ρ‚Ρ€Π΅Ρ… ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Ρ… ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊ:

  • table_size - Ρ€Π°Π·ΠΌΠ΅Ρ€ основной Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ Π±Π΅Π· ΡƒΡ‡Π΅Ρ‚Π° TOAST-Π΄Π°Π½Π½Ρ‹Ρ….
  • toast_size - Ρ€Π°Π·ΠΌΠ΅Ρ€ TOAST-Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ (Ссли имССтся).
  • total_size - ΠΎΠ±Ρ‰ΠΈΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€ (основная + TOAST Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹).

2. Π’Ρ‹Π±ΠΎΡ€ тСстовых записСй

CREATE TEMP TABLE test_actors AS
SELECT
    *
FROM (
    -- АктСр с ΠΌΠ°Π»Ρ‹ΠΌ количСством Ρ€ΠΎΠ»Π΅ΠΉ
    SELECT
        id,
        ActorFirstName,
        ActorSecondName,
        RolesName,
        'small' AS actor_type,
        jsonb_array_length(RolesName -> 'roles') AS roles_count,
        pg_column_size(RolesName) AS data_size
    FROM
        actors
    WHERE
        pg_column_size(RolesName) < 1000 -- Π“Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎ inline
        AND jsonb_array_length(RolesName -> 'roles') BETWEEN 1 AND 5
    ORDER BY
        pg_column_size(RolesName)
    LIMIT 1) AS small
-- ... Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ для большого Π°ΠΊΡ‚Π΅Ρ€Π° ...

Π‘ΠΊΡ€ΠΈΠΏΡ‚ Π²Ρ‹Π±ΠΈΡ€Π°Π΅Ρ‚ Π΄Π²Π΅ записи Π°ΠΊΡ‚Π΅Ρ€ΠΎΠ²:

  1. МалСнький Π°ΠΊΡ‚Π΅Ρ€ - с Π΄Π°Π½Π½Ρ‹ΠΌΠΈ ΠΌΠ΅Π½Π΅Π΅ 1000 Π±Π°ΠΉΡ‚ ΠΈ Π½Π΅ Π±ΠΎΠ»Π΅Π΅ 5 ролями.
  2. Π‘ΠΎΠ»ΡŒΡˆΠΎΠΉ Π°ΠΊΡ‚Π΅Ρ€ - с Π΄Π°Π½Π½Ρ‹ΠΌΠΈ Π±ΠΎΠ»Π΅Π΅ 10000 Π±Π°ΠΉΡ‚ ΠΈ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅ 200 ролями.

Ѐункция pg_column_size() ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для Ρ‚ΠΎΡ‡Π½ΠΎΠ³ΠΎ опрСдСлСния Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° JSONB-Π΄Π°Π½Π½Ρ‹Ρ… Π² Π±Π°ΠΉΡ‚Π°Ρ….

3. Ѐункция для ΠΌΠ½ΠΎΠ³ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎΠ³ΠΎ обновлСния

CREATE OR REPLACE FUNCTION update_actor_role_year(p_id integer, p_iterations integer)
    RETURNS VOID
    AS $$

Π­Ρ‚Π° функция:

  • ΠŸΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ ID Π°ΠΊΡ‚Π΅Ρ€Π° ΠΈ количСство ΠΈΡ‚Π΅Ρ€Π°Ρ†ΠΈΠΉ.
  • Π’ Ρ†ΠΈΠΊΠ»Π΅ мСняСт Π³ΠΎΠ΄ ΠΏΠ΅Ρ€Π²ΠΎΠΉ Ρ€ΠΎΠ»ΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ '1900' ΠΈ '2023'.
  • Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ jsonb_set() для измСнСния ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ Π²Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ поля JSONB Π±Π΅Π· ΠΏΠΎΠ»Π½ΠΎΠΉ Π·Π°ΠΌΠ΅Π½Ρ‹ всСго Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°.

4. Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ΠΈΡ ΠΈ обновлСния

Π‘ΠΊΡ€ΠΈΠΏΡ‚ выполняСт нСсколько ΠΈΠ·ΠΌΠ΅Ρ€Π΅Π½ΠΈΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹:

  1. ΠΠ°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ΅ состояниС.
  2. ПослС 100 ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΉ малСнького Π°ΠΊΡ‚Π΅Ρ€Π°.
  3. ПослС 100 ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΉ большого Π°ΠΊΡ‚Π΅Ρ€Π°.

ВсС измСрСния ΡΠΎΡ…Ρ€Π°Π½ΡΡŽΡ‚ΡΡ Π² Ρ‚Π°Π±Π»ΠΈΡ†Π΅ size_measurements для ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ Π°Π½Π°Π»ΠΈΠ·Π°.

5. Анализ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€Π°

WITH size_changes AS (
    SELECT
        -- Для ΠΌΠ°Π»ΠΎΠ³ΠΎ Π°ΠΊΡ‚Π΅Ρ€Π° (ΠΈΠ·ΠΌΠ΅Ρ€Π΅Π½ΠΈΠ΅ Π΄ΠΎ ΠΈ послС Π΅Π³ΠΎ обновлСния)
        m1.actor_type,
        m1.id,
        m2.table_size - m1.table_size AS table_size_change,
        -- ... ΠΊΠΎΠ΄ ...
    FROM 
        size_measurements m1,
        size_measurements m2
    WHERE 
        m1.measurement_point = 'before_update'
        AND m2.measurement_point = 'after_small_update'
        AND m1.actor_type = 'small'
        AND m2.actor_type = 'small'
    UNION ALL
    -- Для большого Π°ΠΊΡ‚Π΅Ρ€Π° (ΠΈΠ·ΠΌΠ΅Ρ€Π΅Π½ΠΈΠ΅ послС обновлСния ΠΌΠ°Π»ΠΎΠ³ΠΎ ΠΈ послС обновлСния большого)
    SELECT
        -- ... ΠΊΠΎΠ΄ ...
)

Π—Π΄Π΅ΡΡŒ происходит вычислСниС фактичСских ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π°ΠΊΡ‚Π΅Ρ€Π° с использованиСм CTE (Common Table Expression).

Common Table Expression (CTE) ΠΈΠ»ΠΈ ΠΎΠ±Ρ‰Π΅Π΅ Ρ‚Π°Π±Π»ΠΈΡ‡Π½ΠΎΠ΅ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ - это ΠΌΠΎΡ‰Π½Ρ‹ΠΉ инструмСнт SQL, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠΉ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Π½Π°Π±ΠΎΡ€Ρ‹ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ², ΠΊ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±Ρ€Π°Ρ‰Π°Ρ‚ΡŒΡΡ Π² Ρ€Π°ΠΌΠΊΠ°Ρ… основного SQL-запроса.

ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ характСристики CTE:

  1. Π’Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ΅ сущСствованиС: CTE сущСствуСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π²ΠΎ врСмя выполнСния запроса, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΎΠ½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΎ.
  2. Бинтаксис: опрСдСляСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ³ΠΎ слова WITH, Π·Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ слСдуСт имя выраТСния ΠΈ ΠΎΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ список столбцов.
  3. ΠžΠ±Π»Π°ΡΡ‚ΡŒ видимости: Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ CTE доступны Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² ΠΏΡ€Π΅Π΄Π΅Π»Π°Ρ… запроса, содСрТащСго Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ WITH.

ΠšΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ особСнности Ρ€Π°Π±ΠΎΡ‚Ρ‹ скрипта

  1. ΠœΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ Ρ€Π°Π·ΠΌΠ΅Ρ€Π°: скрипт отслСТиваСт Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ±Ρ‰ΠΈΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€, Π½ΠΎ ΠΈ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ основной ΠΈ TOAST-Ρ‚Π°Π±Π»ΠΈΡ†, Ρ‡Ρ‚ΠΎ Π²Π°ΠΆΠ½ΠΎ для понимания ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° Ρ€Π°Π±ΠΎΡ‚Ρ‹ с большими Π΄Π°Π½Π½Ρ‹ΠΌΠΈ.
  2. ΠœΠ½ΠΎΠ³ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎΠ΅ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅: 100 ΠΈΡ‚Π΅Ρ€Π°Ρ†ΠΈΠΉ обновлСния Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΡŽΡ‚, Ρ‡Ρ‚ΠΎ эффСкт Π±ΡƒΠ΄Π΅Ρ‚ Π·Π°ΠΌΠ΅Ρ‚Π΅Π½ ΠΈ статистичСски Π·Π½Π°Ρ‡ΠΈΠΌΡ‹ΠΌ.
  3. Π¦Π΅Π»Π΅Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½Π½Ρ‹ΠΉ Π²Ρ‹Π±ΠΎΡ€ записСй: скрипт Ρ‚Ρ‰Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ Π²Ρ‹Π±ΠΈΡ€Π°Π΅Ρ‚ Π°ΠΊΡ‚Π΅Ρ€ΠΎΠ² с Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ характСристиками для дСмонстрации Ρ€Π°Π·Π»ΠΈΡ‡ΠΈΠΉ.

Π’Ρ‹Π²ΠΎΠ΄ скрипта

ПослС запуска скрипта Π² консоли ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ ΠΈΠ·ΠΌΠ΅Ρ€Π΅Π½ΠΈΠΉ ΠΈ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΉ:

CREATE FUNCTION
psql:3-update-year/update-year.sql:18: NOTICE:  table "test_actors" does not exist, skipping
DROP TABLE
SELECT 2
 actor_type |   id    |     name     | roles_count | jsonb_size_bytes | jsonb_size_kb | first_role_year 
------------+---------+--------------+-------------+------------------+---------------+-----------------
 small      |  139194 | Tibor BalΓ‘zs |           1 |               63 |          0.06 | 2009
 large      | 2555314 | Frank Welker |        5046 |           212356 |        207.38 | 2023
(2 rows)

CREATE FUNCTION
 table_size | toast_size | total_size 
------------+------------+------------
  903233536 | 1021689856 | 1924923392
(1 row)

SELECT 2
   id   | actorfirstname | actorsecondname | roles_count 
--------+----------------+-----------------+-------------
 139194 | Tibor          | BalΓ‘zs          |           1
(1 row)

psql:3-update-year/update-year.sql:118: NOTICE:  Updated small actor (ID: 139194) 100 times
DO
INSERT 0 2
   id    | actorfirstname | actorsecondname | roles_count 
---------+----------------+-----------------+-------------
 2555314 | Frank          | Welker          |        5046
(1 row)

psql:3-update-year/update-year.sql:143: NOTICE:  Updated large actor (ID: 2555314) 100 times
DO
INSERT 0 2
 actor_type |   id    | ИзмСнСниС основной Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ (Π±Π°ΠΉΡ‚) | ИзмСнСниС TOAST-Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ (Π±Π°ΠΉΡ‚) | ΠžΠ±Ρ‰Π΅Π΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ (Π±Π°ΠΉΡ‚) | ΠžΠ±Ρ‰Π΅Π΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ (KiB) 
------------+---------+-----------------------------------+--------------------------------+------------------------+-----------------------
 large      | 2555314 |                                 0 |                        4169728 |                4169728 |               4072.00
 small      |  139194 |                                 0 |                              0 |                      0 |                  0.00
(2 rows)

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ ΠΈ Π²Ρ‹Π²ΠΎΠ΄Ρ‹

ΠŸΡ€ΠΈΠ²Π΅Π΄Ρ‘ΠΌ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΡƒΡŽ ΠΈΠ· Π²Ρ‹Π²ΠΎΠ΄Π° скрипта ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€Π°Ρ… Ρ‚Π°Π±Π»ΠΈΡ† ΠΈ измСнСниях Π² Π±ΠΎΠ»Π΅Π΅ ΡƒΠ΄ΠΎΠ±Π½ΠΎΠΌ Π²ΠΈΠ΄Π΅:

actor_type id ИзмСнСниС основной Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ (Π±Π°ΠΉΡ‚) ИзмСнСниС TOAST-Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ (Π±Π°ΠΉΡ‚) ΠžΠ±Ρ‰Π΅Π΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ (Π±Π°ΠΉΡ‚) ΠžΠ±Ρ‰Π΅Π΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ (ΠšΠ‘)
large 2555314 0 4169728 4169728 4072.00
small 139194 0 0 0 0.00
  1. Для Π°ΠΊΡ‚Π΅Ρ€Π° с ΠΌΠ°Π»Ρ‹ΠΌΠΈ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ (inline):

    • ΠžΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΠΈΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Π² Ρ€Π°Π·ΠΌΠ΅Ρ€Π΅ основной Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹;
    • TOAST-Ρ‚Π°Π±Π»ΠΈΡ†Π° Π½Π΅ измСнилась, Ρ‡Ρ‚ΠΎ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΠΎ, вСдь Π΄Π°Π½Π½Ρ‹Π΅ хранятся нСпосрСдствСнно Π² строкС.
  2. Для Π°ΠΊΡ‚Π΅Ρ€Π° с большими Π΄Π°Π½Π½Ρ‹ΠΌΠΈ (TOAST):

    • Π—Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΠ΅ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° TOAST-Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ ΠΈΠ·-Π·Π° особСнности ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° TOAST:
      • ΠŸΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΈ создаСтся новая вСрсия TOAST-Π΄Π°Π½Π½Ρ‹Ρ…;
      • Бтарая вСрсия помСчаСтся ΠΊΠ°ΠΊ Π½Π΅Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ, Π½ΠΎ мСсто Π½Π΅ освобоТдаСтся;
      • Для освобоТдСния мСста трСбуСтся Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ VACUUM.
  3. ΠžΠ±Ρ‰ΠΈΠ΅ Π²Ρ‹Π²ΠΎΠ΄Ρ‹:

    • ЧастыС обновлСния Π±ΠΎΠ»ΡŒΡˆΠΈΡ… JSONB-ΠΏΠΎΠ»Π΅ΠΉ ΠΌΠΎΠ³ΡƒΡ‚ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ сущСствСнноС "разрастаниС" (bloating) TOAST-Ρ‚Π°Π±Π»ΠΈΡ†;
    • Для Π±Π°Π· Π΄Π°Π½Π½Ρ‹Ρ… с Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹ΠΌΠΈ обновлСниями Π±ΠΎΠ»ΡŒΡˆΠΈΡ… JSON-Π΄Π°Π½Π½Ρ‹Ρ… Π²Π°ΠΆΠ½ΠΎ рСгулярно Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ VACUUM;
    • ΠŸΡ€ΠΈ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ структуры Π΄Π°Π½Π½Ρ‹Ρ… стоит Π²Ρ‹Π½ΠΎΡΠΈΡ‚ΡŒ часто обновляСмыС поля Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΊΠΎΠ»ΠΎΠ½ΠΊΠΈ, Ссли это Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ.

Π­Ρ‚ΠΎΡ‚ экспСримСнт наглядно дСмонстрируСт ΠΎΠ΄Π½Ρƒ ΠΈΠ· Π²Π°ΠΆΠ½Ρ‹Ρ… особСнностСй Ρ€Π°Π±ΠΎΡ‚Ρ‹ с JSONB Π² PostgreSQL ΠΈ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ ΠΏΠΎΠ½ΡΡ‚ΡŒ, ΠΏΠΎΡ‡Π΅ΠΌΡƒ частыС обновлСния Π±ΠΎΠ»ΡŒΡˆΠΈΡ… JSON-Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² ΠΌΠΎΠ³ΡƒΡ‚ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ с ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒΡŽ ΠΈ дисковым пространством.

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

Π’ Ρ…ΠΎΠ΄Π΅ выполнСния практичСского задания Π±Ρ‹Π»ΠΈ ΠΏΡ€ΠΎΠ²Π΅Π΄Π΅Π½Ρ‹ комплСксныС исслСдования особСнностСй Ρ€Π°Π±ΠΎΡ‚Ρ‹ с JSONB-Π΄Π°Π½Π½Ρ‹ΠΌΠΈ Π² PostgreSQL ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Ρ‹ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ Π²Ρ‹Π²ΠΎΠ΄Ρ‹:

  1. ΠŸΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ доступа ΠΊ JSONB Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ зависит ΠΎΡ‚ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° Π΄Π°Π½Π½Ρ‹Ρ…:

    • Для Π΄Π°Π½Π½Ρ‹Ρ… Π΄ΠΎ 2KB (inline Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅) срСднСС врСмя доступа составило ΠΎΠΊΠΎΠ»ΠΎ 5844 наносСкунд;
    • Для Π΄Π°Π½Π½Ρ‹Ρ… Π±ΠΎΠ»Π΅Π΅ 2KB (TOAST Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅) врСмя доступа увСличиваСтся Π΄ΠΎ 37476 наносСкунд (~6.4 Ρ€Π°Π· ΠΌΠ΅Π΄Π»Π΅Π½Π½Π΅Π΅);
    • ПослС ΠΏΠΎΡ€ΠΎΠ³Π° Π² 2KB Π½Π°Π±Π»ΡŽΠ΄Π°Π΅Ρ‚ΡΡ линСйная Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ скорости ΠΎΡ‚ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° Π΄Π°Π½Π½Ρ‹Ρ….
  2. ΠœΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ TOAST Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ влияСт Π½Π° использованиС дискового пространства ΠΏΡ€ΠΈ обновлСниях:

    • ΠŸΡ€ΠΈ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΈ Π½Π΅Π±ΠΎΠ»ΡŒΡˆΠΈΡ… JSONB-ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² (inline) ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° Π±Π°Π·Ρ‹ Π½Π΅Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΈΠ»ΠΈ отсутствуСт вовсС;
    • ΠŸΡ€ΠΈ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΈ Π±ΠΎΠ»ΡŒΡˆΠΈΡ… JSONB-ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² (TOAST) Π½Π°Π±Π»ΡŽΠ΄Π°Π΅Ρ‚ΡΡ сущСствСнноС ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΠ΅ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° TOAST-Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹;
    • Π­Ρ‚ΠΎ происходит ΠΈΠ·-Π·Π° стратСгии копирования ΠΏΡ€ΠΈ запросС: старая вСрсия остаётся Π² TOAST-Ρ‚Π°Π±Π»ΠΈΡ†Π΅ Π΄ΠΎ выполнСния VACUUM.
  3. Π Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с JSONB ΠΈΠΌΠ΅ΡŽΡ‚ Ρ€Π°Π·Π½ΡƒΡŽ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ:

    • ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ @> с индСксом GIN(jsonb_path_ops) Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ эффСктивно;
    • ΠžΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΊ Π³Π»ΡƒΠ±ΠΎΠΊΠΎ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΌ полям Ρ‡Π΅Ρ€Π΅Π· ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ -> ΠΈ ->> ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΌΠ΅Π΄Π»Π΅Π½Π½Ρ‹ΠΌ для Π±ΠΎΠ»ΡŒΡˆΠΈΡ… Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ²;
    • JSONPath обСспСчиваСт Π±ΠΎΠ»Π΅Π΅ эффСктивный ΠΈ Π΄Π΅ΠΊΠ»Π°Ρ€Π°Ρ‚ΠΈΠ²Π½Ρ‹ΠΉ способ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΌΠΈ структурами.

PostgreSQL с Π΅Π³ΠΎ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ JSONB прСдоставляСт ΠΌΠΎΡ‰Π½Ρ‹ΠΉ инструмСнтарий для Ρ€Π°Π±ΠΎΡ‚Ρ‹ со слабоструктурированными Π΄Π°Π½Π½Ρ‹ΠΌΠΈ, ΠΎΠ΄Π½Π°ΠΊΠΎ для достиТСния ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½ΠΎΠΉ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠΎΠ½ΠΈΠΌΠ°Ρ‚ΡŒ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠ΅ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΡ‹ хранСния ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Ρ‚Π°ΠΊΠΈΡ… Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ.

About

PostgreSQL JSONB performance analysis using IMDB dataset. Includes data parsing from actors.list.txt, JSONB query examples, access time measurements across the 2KB TOAST threshold, and update impact analysis. Demonstrates the performance characteristics of PostgreSQL's JSONB storage with visualizations and detailed findings.

Topics

Resources

Stars

Watchers

Forks

Contributors