Tune PostgreSQL for pgvector
Vektorsøgningsarbejdsbelastninger stiller andre krav til PostgreSQL sammenlignet med traditionelle transaktionelle eller analytiske forespørgsler. At forstå disse forskelle hjælper dig med at justere konfigurationsparametre for at optimere forespørgselslatens, hukommelsesforbrug og beregningseffektivitet for AI-applikationer.
Notat
Kodeeksempler i denne enhed demonstrerer konfigurationsmønstre for PostgreSQL og pgvector. Parameterværdierne vist er udgangspunkter for tuning. Optimale indstillinger afhænger af din specifikke arbejdsbyrde, datasætstørrelse og hardware. Benchmark altid ændringer i et testmiljø, før du anvender dem i produktion.
Pgvektor-beregnings- og hukommelseskrav
Vektorlighedssøgning indebærer beregning af afstande mellem en forespørgselsvektor og potentielt millioner af lagrede vektorer. Dette beregningsmønster adskiller sig fundamentalt fra traditionelle databaseoperationer, der filtrerer rækker baseret på indekserede kolonner eller joiner tabeller på nøgleværdier.
Når du udfører en vektorlighedsforespørgsel, skal pgvector beregne afstanden mellem din forespørgselsvektor og kandidatvektorerne. For en 1536-dimensionel indlejring (almindeligt for OpenAI-modeller) involverer hver afstandsberegning 1.536 flydende kommatal-operationer. Søgning på en million vektorer uden indeks kræver over 1,5 milliarder flydende komma-operationer pr. forespørgsel. De tre afstandsfunktioner har forskellige beregningsomkostninger, som påvirker dit valg baseret på dine dataegenskaber og ydelseskrav.
-
L2 (euklidisk) afstand: Bruger operatoren
<->og beregner kvadratroden af summen af kvadrerede forskelle. Dette er den mest beregningsmæssigt krævende løsning. -
Cosinusafstand: Bruger operatoren
<=>og måler vinklen mellem vektorer. Den normaliserer vektorer internt, tilføjer beregning, men giver skaleringsinvariant lighed. -
Indre produkt: Bruger operatoren
<#>og beregner prikproduktet. Dette er den hurtigste operation, men kræver forudnormaliserede vektorer for meningsfulde lighedssammenligninger.
For anbefalingsmotorer og semantisk søgning foretrækkes cosinusafstand ofte, fordi den håndterer vektorer af varierende størrelser konsekvent. Hvis dine indlejringer allerede er normaliserede (mange indlejrings-API'er returnerer normaliserede vektorer), giver det indre produkt tilsvarende resultater med mindre beregning.
Vektorkolonner bruger betydelig lagerplads sammenlignet med traditionelle datatyper. En enkelt 1536-dimensionel vektor gemt som float4 (enkelt præcision) kræver 6.144 bytes plus overhead. En tabel med en million produktindlejringer kræver cirka 6 GB bare for vektorkolonnen. Når PostgreSQL behandler vektorforespørgsler, indlæser den vektordata i hukommelsen. Forholdet mellem tilgængelig hukommelse og vektordatastørrelse påvirker direkte, om forespørgsler kan udføres effektivt i hukommelsen eller skal læses gentagne gange fra disken.
Højere-dimensionelle indlejringer giver mere semantisk opløsning, men øger både lager- og beregningsomkostninger kvadratiksk. En 3072-dimensionel vektor (brugt af nogle nyere indlejringsmodeller) kræver fire gange så meget afstandsberegning og dobbelt så meget lagring som en 1536-dimensionel vektor. Overvej dine nøjagtighedskrav, når du vælger indlejringsdimensioner. For mange anbefalings- og søgeapplikationer giver 768 eller 1.024 dimensioner tilstrækkelig kvalitet med væsentligt lavere ressourceforbrug.
Hukommelseskonfiguration til vektorarbejdsbelastninger
PostgreSQL's hukommelsesparametre påvirker vektorforespørgselspræstationen betydeligt. Korrekt tuning sikrer, at vektorindekser og ofte tilgåede data forbliver i hukommelsen, hvilket reducerer dyre diskoperationer.
Parameteren shared_buffers styrer PostgreSQL's delte hukommelsescache, hvor ofte tilgåede datasider befinder sig. Til vektorarbejdsbelastninger bør denne cache være stor nok til at rumme dine vektorindekser og hot data. En cache-hit ratio under 99% for vektortunge arbejdsbelastninger indikerer, at det shared_buffers måske er for lille. På Azure Database for PostgreSQL justeres denne parameter automatisk baseret på dit compute-tier, men du kan justere den inden for det tilladte interval for dit tier. For dedikerede vektorsøgningsarbejdsbelastninger skal du sigte efter shared_buffers store nok til at rumme dine vektorindekser plus en margin til andre cachede data. Et udgangspunkt er 25% tilgængelig hukommelse, med stigninger baseret på overvågning. Følgende forespørgsler hjælper dig med at tjekke dine nuværende indstillinger og cache-ydeevne.
-- Check current setting
SHOW shared_buffers;
-- View buffer cache hit ratio
SELECT
sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read)) AS cache_hit_ratio
FROM pg_statio_user_tables;
Parameteren work_mem styrer den hukommelse, der er tilgængelig for individuelle forespørgselsoperationer som sortering og hash-joins. Vektorlighedsforespørgsler, især dem der kombinerer vektorsøgning med filtrering og rækkefølge, drager fordel af tilstrækkelig work_mem. Standarden work_mem (typisk 4 MB) er ofte for lille til vektoroperationer, der skal sortere resultaterne efter lighed. Du kan øge denne værdi for sessioner eller forespørgsler, der udfører vektorsøgninger med store resultatmængder ved hjælp af SET work_mem = '256MB';. Vær forsigtig med globale stigninger work_mem , fordi indstillingen gælder for hver operation pr. forbindelse, så en server, der håndterer 100 samtidige forbindelser med komplekse forespørgsler, kan forbruge 100 × work_mem × operationer pr. forespørgsel i hukommelsen. For vektorarbejdsbelastninger bør du overveje at sætte work_mem specifikke forespørgsler på sessionsniveau i stedet for globalt.
Parameteren effective_cache_size fortæller forespørgselsplanlæggeren, hvor meget hukommelse der er tilgængelig til caching, inklusive både PostgreSQL's shared_buffers og operativsystemets filcache. Denne indstilling allokerer ikke hukommelse, men påvirker, om planlæggeren vælger indeksscanninger frem for sekventielle scanninger. Indsat effective_cache_size til cirka 75% samlet systemhukommelse på dedikerede databaseservere. Højere værdier opfordrer planlæggeren til at bruge indekser, hvilket typisk er gavnligt for vektorsøgning. På Azure Database for PostgreSQL konfigureres dette automatisk baseret på dit tier.
Forespørgselsplanlæggerindstillinger til vektorsøgning
PostgreSQL's forespørgselsplanlægger træffer beslutninger om, hvordan forespørgsler skal udføres, baseret på omkostningsestimater. Flere parametre påvirker disse estimater, og justering af dem til moderne SSD-lagring forbedrer planlægningen af vektorforespørgsler.
Parameteren random_page_cost estimerer omkostningerne ved at læse en tilfældig diskside i forhold til en sekventiel side. Standardværdien i 4.0 afspejler roterende diskkarakteristika, hvor tilfældig adgang er betydeligt langsommere end sekventiel adgang. Azure Database for PostgreSQL bruger SSD-lagring, hvor tilfældig og sekventiel adgang har lignende ydeevne. Sænkning random_page_cost til 1,1-1,5 opfordrer planlæggeren til lettere at bruge indeksscanninger, hvilket gavner vektorsøgninger, der får adgang til spredte datasider. Du kan justere denne indstilling med SET random_page_cost = 1.1;.
Parameteren effective_io_concurrency fortæller PostgreSQL, hvor mange samtidige disk-I/O-operationer lagringssystemet kan håndtere. Højere værdier gør det muligt for bitmap-heap-scanninger at forudhente flere sider parallelt. SSD-lagring håndterer samtidig I/O godt, så sæt effective_io_concurrency til 200 for SSD-baseret Azure Database for PostgreSQL-instanser. Dette forbedrer ydeevnen for forespørgsler, der kombinerer vektorlighed med metadatafiltrering.
Og parallel_tuple_costparallel_setup_cost parametrene styrer, når PostgreSQL bruger parallel forespørgselskørsel. Vektoroperationer kan drage fordel af parallelisme, især for sekventielle scanninger på store tabeller. Lavere værdier for parallel_tuple_cost (standard 0.1) og parallel_setup_cost (standard 1000) opfordrer til parallel eksekvering. For vektorarbejdsbelastninger med store tabeller kan det at aktivere parallelisme markant reducere forespørgselstiden, når indekser ikke bruges. Du kan tjekke dine nuværende parallelindstillinger ved at bruge SHOW parallel_tuple_cost;, SHOW parallel_setup_cost;, og SHOW max_parallel_workers_per_gather;.
Konfigurer pgvektorspecifikke parametre
Pgvector-udvidelsen giver konfigurationsparametre, der styrer nøjagtigheds-hastigheds-afvejningen for indeksbaserede søgninger. Disse parametre er afgørende for at tune ydeevnen for vektorforespørgsler.
Når IVFFlat-indekser bruges, styrer parameteren ivfflat.probes , hvor mange indekspartitioner (lister) der søges efter for hver forespørgsel. Højere værdier øger genkaldelsen (at finde flere af de sande nærmeste naboer), men langsomme forespørgsler. Denne afvejning er central for IVFFlats ydelsestuning. Du balancerer risikoen for at misse gode matches mod omkostningerne ved at søge flere partitioner. Standardværdien 1 søger kun i den mest lovende partition, som er hurtig, men kan overse relevante resultater, der er gemt i tilstødende partitioner. For anbefalingsmotorer, hvor manglende et godt match forringer brugeroplevelsen, start med ivfflat.probes at sætte til 5-10% af din lists parameter og juster baseret på målt genkaldelse.
-- Configure IVFFlat search depth
SET ivfflat.probes = 10;
-- Execute vector search
SELECT id, name, embedding <=> $1 AS distance
FROM products
ORDER BY embedding <=> $1
LIMIT 10;
For HNSW-indekser styrer parameteren hnsw.ef_search størrelsen på den dynamiske kandidatliste under søgning. Større værdier udforsker mere af grafen og forbedrer genkaldelsen på bekostning af hastighed. I modsætning til IVFFlats diskrete partitioner betyder HNSW's grafstruktur, at denne parameter påvirker, hvor grundigt algoritmen undersøger naboforbindelser, før den returnerer resultater. Standardværdien på 40 giver en rimelig balance for mange arbejdsbelastninger. For krav til høj nøjagtighed (såsom at finde de sande top-10 kampe), øg til 100-200. For latenskritiske applikationer, hvor omtrentlige resultater er acceptative, kan værdier så lave som 20 fungere. Konfigurer hnsw.ef_search med før SET hnsw.ef_search = 100; du udfører din vektorsøgning. Den optimale værdi afhænger af dine nøjagtighedskrav og latenstidsbudget. Benchmark med repræsentative forespørgsler for at finde den rette balance til din ansøgning.
Overvåg og mål præstation
Tuning uden måling er gætteri. Brug PostgreSQL's indbyggede værktøjer og Azure Monitor til at forstå forespørgselsadfærd og validere konfigurationsændringer.
Kommandoen EXPLAIN ANALYZE viser, hvordan PostgreSQL udfører en forespørgsel og giver faktisk timing-information. For vektorforespørgsler afslører dette, om indekser bruges, og hvor tiden bruges. At forstå eksekveringsplanen hjælper dig med at identificere, om dårlig ydeevne skyldes manglende indekser, suboptimale parameterindstillinger eller problemer med datafordeling. Kør EXPLAIN ANALYZE før din vektorforespørgsel for at se eksekveringsplanen. Se efter Index Scan med [index_name] (angiver at vektorindekset bruges), Seq Scan (angiver en sekventiel scanning, som er langsom for store tabeller), faktiske tidsværdier (viser hvor eksekveringstiden er brugt) og rækkeoptælling (hjælp med at identificere, om filtreringen fungerer effektivt). Hvis du ser sekventielle scanninger, hvor du forventer indeksbrug, så tjek at forespørgslens afstandsoperator matcher indeksets operatorklasse (for eksempel ved at bruge <=> med et indeks oprettet med vector_cosine_ops).
Nogle gange vælger PostgreSQL ikke at bruge et tilgængeligt indeks. Almindelige årsager til vektorforespørgsler inkluderer forespørgsler, der returnerer en stor del af tabellen (indeksoverhead overstiger sekventiel scanning), forældede statistikker efter betydelige dataændringer eller en afstandsoperator, der ikke matcher indeksets operatorklasse. Løb ANALYZE products; for at opdatere statistikker for præcis planlægning. Du kan tjekke indeksoplysninger med SELECT indexname, indexdef FROM pg_indexes WHERE tablename = 'products';.
Azure Database for PostgreSQL eksponerer metrikker gennem Azure Monitor, der hjælper med at identificere performance-flaskehalse. Overvåg CPU-procent (høj vedvarende CPU indikerer compute-bound vektoroperationer), hukommelsesprocent (nærmende grænser antyder øget beregningsniveau eller optimering af forespørgsler), Storage IO-procent (høje værdier indikerer, at data ikke passer i cachen), og aktive forbindelser (nærmende grænser indikerer, at forbindelsespooling kan hjælpe). Opsæt advarsler for disse målinger for at fange ydelsesforringelse, før det påvirker brugerne.
Bedste praksis for pgvector-tuning
Effektiv tuning følger en systematisk tilgang frem for tilfældige parameterændringer.
- Etabler først baselines: Mål forespørgselsforsinkelse og ressourceforbrug, før du foretager ændringer. Uden baselines kan du ikke afgøre, om ændringer hjælper eller skader.
- Ændr én parameter ad gangen: Flere samtidige ændringer gør det umuligt at tilskrive forbedringer eller regressioner til specifikke indstillinger.
- Test med produktionslignende data: Forespørgselsydelsen varierer dramatisk med datastørrelse og fordeling. Tuning på små testdatasæt producerer ofte indstillinger, der fejler i stor skala.
- Overvåg for regressioner: Parametre, der forbedrer vektorsøgning, kan have en negativ indvirkning på andre arbejdsbelastninger. Overvåg den overordnede systemtilstand efter ændringer.
- Dokumentér dine indstillinger: Notér, hvad du ændrede, hvorfor, og hvilken effekt det havde. Denne dokumentation er uvurderlig ved fejlfinding af fremtidige problemer.