JSONB-operaattorit ja sisältökyselyt
Käyttäkää sisältö- ja polkuoperaattoreita, joita GIN-indeksit voivat todella nopeuttaa.
JSONB-operaattorit ja sisältökyselyt on ilmainen PostgreSQL:n suorituskyky ja kyselyjen optimointi-oppitunti CoddyKitissä. Tämä on oppitunti 1/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu PostgreSQL:n suorituskyky ja kyselyjen optimointi-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. PostgreSQL:n suorituskyky ja kyselyjen optimointi-kurssilla on yhteensä 4 oppituntia.
Miksi operaattorin valinta ratkaisee indeksin käytön
PostgreSQL:ssä jsonb-tyyppistä saraketta voidaan hakea monella eri tavalla, mutta kaikki operaattorit eivät voi käyttää indeksiä. Suorituskyky riippuu tässä lähes kokonaan sellaisten operaattorien valinnasta, joita GIN-indeksi voi nopeuttaa.
- GIN-indeksi (Generalized Inverted Index) tallentaa JSON-dokumenttien sisällä olevat avaimet ja arvot, joten haut voivat ohittaa koko taulun läpikäynnin.
- Kaksi tärkeintä operaattoria ovat sisältäminen (
@>) ja avaimen olemassaolo (?,?|,?&).
Tässä oppitunnissa opetellaan tarkalleen, mitkä operaattorit nämä ovat ja miten kyselyitä kirjoitetaan niin, että ne pysyvät indeksiystävällisinä.
Sisältämisoperaattori @>
Sisältämisoperaattori @> kysyy: sisältääkö vasemmanpuoleinen JSONB oikeanpuoleisen JSONB:n? Oikea puoli on katkelma, ja Postgres tarkistaa, että sen jokainen avain ja arvo esiintyy vasemmanpuoleisessa dokumentissa.
'{"a":1,"b":2}' @> '{"a":1}'on tosi.'{"a":1}' @> '{"a":1,"b":2}'on epätosi (oikea puoli sisältää enemmän).
Tämä on rivien suodattamisen perustyökalu: WHERE data @> '{"status":"active"}' löytää jokaisen rivin, jonka JSON sisältää kyseisen avain-arvoparin.
SELECT '{"a":1,"b":2}'::jsonb @> '{"a":1}'::jsonb AS contains_a,
'{"a":1}'::jsonb @> '{"a":1,"b":2}'::jsonb AS contains_both;GIN-indeksin luominen sisältämistä varten
Tavallinen GIN-indeksi jsonb-sarakkeessa tukee sekä sisältämis- että avaimen olemassaolo -operaattoreita. Tämä on ensimmäinen indeksi, jota kannattaa kokeilla.
- Oletusarvoinen
jsonb_ops-operaattoriluokka indeksoi jokaisen avaimen ja arvon. - Se nopeuttaa operaattoreita
@>,?,?|ja?&.
Kun indeksi on luotu kerran, suodattimet, jotka aiemmin kävivät läpi koko taulun, muuttuvat bittikarttaindeksihauiksi.
CREATE INDEX idx_events_data
ON events
USING GIN (data);Sisältämissuodattimet WHERE-lauseessa
Kun GIN-indeksi on olemassa, kirjoita suodatin sisältämistarkistuksena, jotta suunnittelija voi käyttää sitä. Myös sisäkkäisen katkelman täsmäytys toimii, koska sisältäminen on rekursiivista.
- Ylimmän tason täsmäytys:
data @> '{"status":"active"}'. - Sisäkkäinen täsmäytys:
data @> '{"user":{"plan":"pro"}}'.
Huomaa, että oikealla puolella välitetään JSON-olioliteraali, ei sarakeviitettä tai funktiokutsua. Juuri tämä literaalin muoto tekee kyselystä indeksikelpoisen.
SELECT id, created_at
FROM events
WHERE data @> '{"user":{"plan":"pro"}}'
ORDER BY created_at DESC
LIMIT 50;Avaimen olemassaolo -operaattorit ? ?| ?&
Joskus haluat tietää vain, onko avain olemassa, sen arvosta riippumatta. Olemassaolo-operaattorit hoitavat tämän, ja myös GIN-indeksi nopeuttaa niitä.
data ? 'email'— tosi, jos ylimmän tason avainemailon olemassa.data ?| array['phone','email']— tosi, jos vähintään yksi näistä avaimista on olemassa.data ?& array['phone','email']— tosi, jos kaikki nämä avaimet ovat olemassa.
Tärkeää: ? tarkistaa vain ylimmän tason avaimet, ja taulukoissa se tarkistaa, onko merkkijono alkiona.
SELECT '{"email":"x@y.z","phone":"123"}'::jsonb ? 'email' AS has_email,
'{"email":"x@y.z"}'::jsonb ?| array['phone','email'] AS has_any,
'{"email":"x@y.z"}'::jsonb ?& array['phone','email'] AS has_all;Ansa: polun poimintaoperaattorit -> ja ->>
Poimintaoperaattorit vaikuttavat käteviltä, mutta tavallinen GIN-indeksi ei nopeuta niitä:
data -> 'status'palauttaa arvon muodossajsonb.data ->> 'status'palauttaa arvon muodossatext.
Kysely kuten WHERE data ->> 'status' = 'active' pakottaa tekemään järjestyksessä etenevän haun tavallisella GIN-indeksillä, koska indeksi ei indeksoi poimittujen skalaarien vertailuja. Käytä sen sijaan sisältämismuotoa data @> '{"status":"active"}'.
-- Slow on a plain GIN index (seq scan):
SELECT * FROM events WHERE data ->> 'status' = 'active';
-- Fast equivalent (uses GIN):
SELECT * FROM events WHERE data @> '{"status":"active"}';->>-operaattorin pelastaminen lausekeindeksillä
Jos tarvitset todella yhden kentän alue- tai merkkijonokuviovertailuja, oikea työkalu on poimitun tekstin B-puun lausekeindeksi — ei GIN.
- Indeksoi täsmälleen se lauseke, jota kyselyssä käytät.
- Tämän jälkeen vertailut kuten
=,<,>jaBETWEENvoivat käyttää sitä.
Kyselyn lausekkeen on vastattava indeksoitua lauseketta merkki merkiltä, muuten suunnittelija jättää indeksin huomiotta.
CREATE INDEX idx_events_status
ON events ((data ->> 'status'));
-- Now this can use the B-tree index:
SELECT * FROM events WHERE (data ->> 'status') = 'active';jsonb_path_ops: pienempi, nopeampi ja vain sisältämiseen
Vaihtoehtoinen operaattoriluokka jsonb_path_ops indeksoi hajautetut juuresta lehteen kulkevat polut kaikkien avainten sijaan.
- Se tuottaa pienemmän indeksin ja on yleensä nopeampi
@>-kyselyissä. - Haittapuoli: se tukee vain sisältämistä (
@>), ei olemassaolo-operaattoreita?,?|ja?&.
Valitse jsonb_path_ops, kun työkuormasi koostuu pääasiassa sisältämissuodatuksesta etkä koskaan tarvitse avainten olemassaolohakuja.
CREATE INDEX idx_events_data_path
ON events
USING GIN (data jsonb_path_ops);Sisältäminen taulukoita vasten
Sisältämisen tarkistus toimii myös JSON-taulukoiden sisällä, joten se sopii erinomaisesti tunnisteita sisältävään dataan. Kun haluat kysyä, "sisältääkö tämä taulukko arvon", ympäröi arvo taulukolla oikealla puolella.
'["a","b","c"]' @> '["b"]'on tosi.- Tunnisteita sisältävässä dokumentissa
data @> '{"tags":["urgent"]}'löytää rivit, joidentags-taulukossa on alkiourgent.
Tämä pysyy täysin indeksikelpoisena GIN-indeksillä, joten tunnisteiden suodatus skaalautuu hyvin.
SELECT '["a","b","c"]'::jsonb @> '["b"]'::jsonb AS has_b,
'{"tags":["urgent","billing"]}'::jsonb
@> '{"tags":["urgent"]}'::jsonb AS is_urgent;Varmista EXPLAIN-komennolla
Älä oleta, että indeksiä käytetään — varmista se. Suorita EXPLAIN ja etsi GIN-indeksistä Bitmap Index Scan -operaatio. Seq Scan tarkoittaa, että operaattori tai lauseke esti indeksin käytön.
- Hyvä merkki:
Bitmap Index Scan on idx_events_data. - Huono merkki:
Seq Scan on eventsJSON-suodattimen yhteydessä.
Käytä komentoa EXPLAIN (ANALYZE, BUFFERS), jos haluat nähdä myös todellisen ajoitusdatan ja luettujen sivujen määrän.
EXPLAIN (ANALYZE, BUFFERS)
SELECT id FROM events
WHERE data @> '{"status":"active"}';Kaiken yhdistäminen: päätössääntö
Käytä tätä pikasääntöä JSONB-suodatinta kirjoittaessasi:
- Täsmäytätkö avain-arvoparin tai sisäkkäisen katkelman? Käytä
@>-operaattoria ja GIN-indeksiä. - Tarkistatko vain avaimen olemassaolon? Käytä operaattoreita
?/?|/?&oletusarvoisenjsonb_ops-GIN-indeksin kanssa. - Onko työkuorma pelkkää sisältämistä ja haluat pienimmän indeksin? Käytä
jsonb_path_ops-GIN-indeksiä. - Alue- tai merkkijonokuviovrtailu yhdelle skalaarikentälle? Käytä B-puun lausekeindeksiä operaattorille
->>.
Vältä ->>-operaattorin yhtäsuuruussuodattimia ilman vastaavaa lausekeindeksiä — ne käynnistävät järjestyksessä etenevän haun.
Pikatarkistus
Sinulla on oletusarvoinen jsonb_ops-GIN-indeksi sarakkeessa events.data. Mikä WHERE-lauseke voi käyttää tätä indeksiä?
Kertaus
Opit, mitkä JSONB-operaattorit todella hyötyvät indeksoinnista:
- @> (sisältäminen) on ensisijainen GIN-indeksillä nopeutettu suodatin, ja se toimii myös sisäkkäisille objekteille ja taulukoille.
- ?, ?| ja ?& (avaimen olemassaolo) nopeutuvat GIN-indeksillä, mutta vain oletusarvoisen
jsonb_ops-luokan kanssa, ja ne tarkistavat ylimmän tason avaimet. - jsonb_path_ops tarjoaa pienemmän ja nopeamman, vain sisältämiseen tarkoitetun indeksin.
- ->- ja ->>-poimintasuodattimet EIVÄT käytä tavallista GIN-indeksiä. Muotoile ne uudelleen
@>-operaattorilla tai lisää B-puun lausekeindeksi. - Varmista aina
EXPLAIN-komennolla, että saat Bitmap Index Scan -operaation etkä Seq Scan -operaatiota.
Opi SQL tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 22
- Oppitunnit
- 88
Usein kysytyt kysymykset
Onko oppitunti ”JSONB-operaattorit ja sisältökyselyt” ilmainen?
Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa PostgreSQL:n suorituskyky ja kyselyjen optimointi-oppimispolun 3 oppituntia, myös oppitunnin “JSONB-operaattorit ja sisältökyselyt”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. PostgreSQL:n suorituskyky ja kyselyjen optimointi-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”JSONB-operaattorit ja sisältökyselyt”?
Käyttäkää sisältö- ja polkuoperaattoreita, joita GIN-indeksit voivat todella nopeuttaa. Harjoittelet PostgreSQL:n suorituskyky ja kyselyjen optimointi-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni PostgreSQL:n suorituskyky ja kyselyjen optimointi-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin PostgreSQL:n suorituskyky ja kyselyjen optimointi-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 1/4.
Kuinka kauan ”JSONB-operaattorit ja sisältökyselyt”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä PostgreSQL:n suorituskyky ja kyselyjen optimointi-oppitunnilla?
Kyllä. Jokainen PostgreSQL:n suorituskyky ja kyselyjen optimointi-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- JSONB-operaattorit ja sisältökyselyt
- JSONB:n GIN- ja lausekeindeksit
- JSONB:n kyselyt JSONPathilla
- Milloin JSONB kannattaa normalisoida