← Tutti gli articoli

Un vector search benchmark rivela un enorme divario nei tempi di build

Un vector search benchmark rivela un enorme divario nei tempi di build

Un vector search benchmark condotto su sei motori di database ha rilevato che trasformare gli stessi 990.000 embedding in un index interrogabile ha richiesto da 1,9 minuti a 6,7 ore. Percona ha eseguito i test su un'unica macchina, con lo stesso insieme di query e la stessa configurazione dei container, misurando tempo di build, spazio di archiviazione, memoria, accuratezza, throughput, client simultanei, ricerche con filtri e l'effetto della riscrittura del 10% dei dati.

Il corpus era dbpedia-openai-1000k-angular e conteneva 990.000 embedding OpenAI, ciascuno rappresentato da 1.536 numeri float32. Un embedding è una rappresentazione numerica utilizzata per confrontare significato o somiglianza. Ogni motore utilizzava HNSW, ossia Hierarchical Navigable Small World, una struttura a grafo che accelera la ricerca di vettori vicini, con M impostato su 16 e il numero di risultati k impostato su 10. L'host disponeva di un processore Intel Xeon Gold 6230, 80 CPU logiche, AVX-512 e 187,5 GiB di RAM. Al container del database erano assegnate le CPU da 0 a 63 e un limite di memoria di 120,8 GB; un container di test separato disponeva di 16 CPU e 8 GB. La separazione impediva che l'insieme di query conservato da NumPy fosse conteggiato come memoria del database.

I sistemi testati erano il database relazionale open source 11.8.8 con MHNSW, lo stesso database relazionale open source 12.3.2 con MHNSW, AliSQL 8.0.44-2 con VIDX, pgvector 0.8.6 sul database relazionale utilizzato da molte applicazioni web, Valkey 9.1.1 con valkey-search e Percona Search for MongoDB 1.70.3-1 su PSMDB 8.3.8-2. Percona Search era una Technical Preview la cui documentazione indicava che non era destinata alla produzione. I relativi test utilizzavano un index con scalar quantization, che memorizza valori numerici meno precisi per ridurre i requisiti di elaborazione e archiviazione.

Le prestazioni di build variavano drasticamente. Percona Search è diventato interrogabile in 1,9 minuti, Valkey in 4,3 minuti e il database relazionale con pgvector in 40,9 minuti. Il database relazionale ha impiegato 26,9 minuti per il caricamento tramite COPY e 14 minuti per il build dell'index con otto worker. Il database open source 11.8 ha richiesto 3,6 ore, il database open source 12.3 ne ha richieste 5,4 e AliSQL 6,7. MHNSW e VIDX aggiornano il proprio grafo durante ogni INSERT, quindi il caricamento e la costruzione dell'index costituivano un'unica operazione. Le loro velocità variavano da 41 a 76 righe al secondo, rispetto alle 613 di pgvector e alle 30.170 di Valkey.

I sistemi con il build più lento hanno prodotto gli index più piccoli. Il database open source e AliSQL utilizzavano ciascuno 3,9 GiB perché i loro grafi conservavano copie quantizzate a 16 bit dei vettori, mentre pgvector e Valkey indicizzavano valori float32 completi. I soli vettori grezzi occupavano 5,7 GiB. Le dimensioni degli index erano di 7,6 GiB per pgvector, 11,3 GiB per Valkey e 15,1 GiB per Percona Search. Includendo le tabelle, AliSQL utilizzava 14,4 GiB, pgvector 15,2 GiB, il database open source 11.8 e Valkey 18,2 GiB ciascuno e Percona Search 20,9 GiB. L'index di Percona Search è stato successivamente misurato in 7,2 GiB all'inizio del test di churn e Percona non è riuscita a stabilire quale valore rappresentasse lo steady state.

Il picco di memoria residente variava dai 14,3 GiB di Valkey ai 48,8 GiB di Percona Search. Le allocazioni della cache erano specifiche per ciascun motore e quindi non identiche: ai sistemi InnoDB erano assegnati un buffer pool da 42,3 GB e una cache del grafo da 30,2 GB, pgvector disponeva di 72,5 GB di shared_buffers più 12,1 GB di maintenance_work_mem e Valkey aveva 108,7 GB di maxmemory. Percona Search utilizzava la cache WiredTiger predefinita di MongoDB, compresa tra 57 e 64 GB. I build degli index erano limitati a otto thread perché un numero maggiore causava contention e poteva bloccare le scritture negli index già popolati.

L'accuratezza è stata misurata come recall, cioè il numero di vicini più prossimi corretti restituiti dalla ricerca. Con un solo client e una recall di almeno 0,99, il database open source 12.3 ha prodotto 277 query al secondo (QPS), Valkey 264, pgvector 210, AliSQL 126 e il database open source 11.8 soltanto 46. L'index quantizzato di Percona Search ha raggiunto al massimo una recall di 0,892 e quindi non si è qualificato; senza scalar quantization ha registrato 88 QPS alla soglia minima di 0,99. La differenza di 13 QPS tra il database open source 12.3 e Valkey era troppo piccola perché una singola esecuzione potesse distinguerla dal rumore. Inoltre, il database open source 12.3 era compilato con -march=native, diversamente dalle build x86-64-v3 utilizzate per il database open source 11.8, AliSQL e pgvector.

AliSQL ha prodotto un'anomalia senza spiegazione. Con M pari a 16, il throughput è aumentato da 2,6 a 4,4 QPS quando ef_search, ossia la quantità di lavoro di ricerca svolto al momento della query, è salito da 400 a 800, sebbene una maggiore quantità di lavoro non dovrebbe rendere più veloce lo stesso index. Anche la latency mediana è balzata da 6,6 millisecondi con ef_search 80 a 50,8 millisecondi con 120, per poi passare da 191 a 384 millisecondi oltre tale valore. Percona ha contrassegnato questo intervallo come inaffidabile anziché considerarlo un risultato valido.

Anche i risultati relativi alla concurrency richiedono un'attenta interpretazione. Con 32 client ed ef_search 100, Valkey ha raggiunto 5.683 QPS con una p99 latency di 10,2 millisecondi, il che significa che il 99% delle query è stato completato entro tale intervallo. Pgvector ha raggiunto 4.798 QPS con 10,8 millisecondi, mentre Percona Search ha raggiunto 1.844 QPS con 43,5 millisecondi. Pgvector ha prodotto un throughput 21,7 volte superiore rispetto a quello con un solo client. Tuttavia, l'harness disponeva di appena 16 CPU, quindi l'appiattimento delle prestazioni di Valkey e Percona Search tra 16 e 32 client potrebbe riflettere limiti della CPU lato client.

Non sono stati riportati dati con più client per il database open source 11.8, il database open source 12.3 o AliSQL. I loro client Python basati su thread, tutti dotati del connector per il database open source, sono rimasti vicini a una sola query in corso nonostante l'aumento del numero di client. Percona non aveva individuato il meccanismo esatto e non aveva effettuato il profiling dei server, quindi non ha avanzato alcuna conclusione sul loro scaling lato server. Da allora l'harness è stato modificato per eseguire ciascun client in un processo separato del sistema operativo, ma tale revisione era stata testata soltanto con driver sintetici e non era ancora stata utilizzata per misurare nuovamente questi motori.

L'uso di filtri ha messo in evidenza importanti differenze di comportamento. Con una selectivity dell'1%, vale a dire quando soltanto l'1% delle righe soddisfaceva la condizione, Valkey ha restituito una recall di 0,9996 a 8,2 QPS. Il database open source 12.3, il database open source 11.8 e AliSQL continuavano la ricerca dopo l'applicazione del filtro, mantenendo una recall compresa tra 0,9724 e 0,9884, ma scendendo al di sotto di un QPS, con una p99 latency compresa tra 10 e 13 secondi. Percona Search applicava il filtro prima della vector search ed è passato da 71,9 QPS con una selectivity del 10% a 117,5 con l'1%, sebbene la scalar quantization limitasse la recall a 0,8666.

Il comportamento predefinito di pgvector eseguiva prima la ricerca, eliminava le righe che non soddisfacevano la condizione e quindi si arrestava. Con una selectivity dell'1%, tutte le 500 query hanno restituito meno delle dieci righe richieste, producendo una recall di 0,1034 a 237,1 QPS senza alcun errore o avviso. Pgvector 0.8 include iterative scan per gestire questo caso, ma il benchmark non l'ha testato. La lezione pratica è che un completamento rapido non è utile se un'applicazione riceve silenziosamente risultati incompleti.

Dopo l'eliminazione e il reinserimento di 99.000 righe, pgvector è rimasto stabile a 245 QPS, con un aumento dello 0,4%, mentre Valkey è sceso del 4% a 460 QPS. Percona Search è diminuito del 38,9%, fermandosi a 113 QPS, sebbene la recall sia cambiata appena, passando da 0,8432 a 0,8416.

Disponibile anche in: EnglishDeutschShqip