SqliteVec delete using IN is slow and scans every row
@rossdonald ya está trabajando en esto.
Desde el 22/9/2026.
Evaluación
Este issue todavía no se ha evaluado.
Descripción
Summary
Deleting vector rows with a single WHERE key IN (@p0, ...) statement makes SQLite scan every row of the vec0 virtual table, because the vec0 module does not expose IN constraint support, so batch deletes and upserts get slower as the table grows regardless of how many rows actually match.
Steps to reproduce
- Create a vec0 virtual table with a text primary key and a 256-dimension vector:
CREATE VIRTUAL TABLE vec_chunks USING vec0(chunk_id TEXT PRIMARY KEY, embedding float[256])
- Insert 100,000 rows.
- Time these for 200 keys that do not exist in the table, each inside one transaction:
DELETE FROM vec_chunks WHERE chunk_id IN (@d0, @d1, /* 198 more */)
DELETE FROM vec_chunks WHERE chunk_id = @d0; -- repeated per key, reusing one prepared statement
Expected behavior
Deleting by primary key, whether through an IN list or one key at a time, costs roughly the same and scales with the number of keys, not the table size.
Actual behavior
At 100,000 rows the IN-list delete took ~102 ms per 200-key batch. The same 200 keys deleted one at a time took 1.1 to 1.3 ms, about 100x faster. The gap is the same whether the keys exist in the table or not, so it grows with table size rather than match count. The behavior is identical with the newest sqlite-vec release (v0.1.10-alpha.4), so it is not fixed by upgrading the extension.
Analysis
The connector deletes the vector rows of a batch with a single IN-list statement, both in the upsert path and in the batch delete path:
The IN list is generated by the where condition:
Cause
For a virtual table, SQLite can only use a WHERE constraint if the module advertises it through xBestIndex. vec0 advertises the primary key equality constraint, but it does not register IN constraint handling, so with an IN list SQLite falls back to a full scan of the virtual table, visiting every row through xNext and evaluating the IN predicate against each one. The data table is a regular SQLite table with an indexed primary key, so the IN form is fine there, only the vector table is affected.
The same pattern exists on the read path, where vector searches filter the virtual table with key IN (SELECT ...):
That path has not been measured separately, but it plausibly triggers the same scan when combined with data-side filters.
Possible fix
In DoUpsertAsync, For the vector table, replace the IN-list delete with one fixed single-key DELETE (DELETE FROM "vec_t" WHERE "chunk_id" = @key) prepared once per operation.
Environment
- Package: CommunityToolkit.VectorData.SqliteVec 1.0.1-preview
- sqlite-vec 0.1.7-alpha.2.1 and v0.1.10-alpha.4 (both measured)
- Table: 100,000 rows, text primary key, 256-dimension vectors
- Lenguaje dominante
- C#
- Estrellas
- 8
- Forks
- 8
- Merge medio
- 2 d 14 h
- PR fusionados (30 d)
- 5
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de CommunityToolkit/AI
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
CommunityToolkit/AI#19 ·
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
CommunityToolkit/AI#61 ·
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
CommunityToolkit/AI#59 ·
-
Report all Cosmos DB emulator issuesQuizá libre de nuevo @adamsitnik la tomó hace 93 días y no hay ningún pull request abierto. Abierto
CommunityToolkit/AI#23 · 1 asignado ·
-
Make Azure SQL tests conditionalAbierto
Dificultad 4/5 3-5 días Aptitud para principiantes 45/100
CommunityToolkit/AI#20 ·
Todos los issues de CommunityToolkit/AI
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
AvaloniaUI/Avalonia#22420 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 90/100
dotnet/SqlClient#4823 · 1 comentario ·
Los mantenedores suelen responder en 2 días
-
type/automation type/tech-debt
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
Los mantenedores suelen responder en 1 día
-
area-testing p1-recommended
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 85/100
StackExchange/StackExchange.Redis#3269 · 1 comentario ·
Los mantenedores suelen responder en 1 día