Vector Search in open-source MySQL VillageSQL demoed an early, unmerged build of custom HNSW vector indexes for MySQL at Percona Live in Amsterdam on September 9, 2026, adding vector search that stock MySQL 9.x lacks. In the demo, an HNSW-indexed table of 20,000 3-dimensional vectors averaged 0.19 ms per nearest-neighbor query across 50 queries versus 3.82 ms for a full scan, a 20x difference, while returning nine of the true top ten results. VillageSQL's extension framework supplies a custom SVECTOR column type and a custom index type declared with USING EXTENDED(hnsw), which the server plans as a "Custom index distance scan on idx_embedding. Vector search in MySQL: an early look at HNSW and custom indexes in VillageSQL MySQL 9.x added the VECTOR data type so you can store an embedding. You get a VECTOR column, functions to convert to and from text, and VECTOR DIM to ask how wide a vector is. What you don't get is a way to compare two vectors. The 9.x community server has no distance function and no vector index. MySQL 8.4 has none of this at all. You can't add the missing index yourself either because vanilla MySQL's list of index types is fixed to B-tree, R-tree, hash, and full-text. That's where VillageSQL comes in. VillageSQL is the innovation platform for MySQL that adds an extension framework similar to PostgreSQL's extension framework to enable permissionless innovation. Instead of waiting for a feature to be implemented in a few years in a future version of MySQL, new functionality can be dynamically added to a version of MySQL you run today. VillageSQL already supports custom functions and custom data types, and we've been working on custom indexes. With custom indexes, an extension can define a whole index type including how it's stored in InnoDB, how it's built as rows arrive, and how it's searched. The server treats the custom index as a first-class index, the same as the built-in index types. The server even plans queries against the custom index and reports it by name. Vector search is a key feature for AI-era applications, so that's the first use case for custom indexes we are building. At Percona Live in Amsterdam on September 9, 2026, we demoed an early build of this vector work not yet merged . Below is the annotated demo. Start with a server The demo starts by installing VillageSQL. You copy one line from the website, paste it into a terminal, and you have a prebuilt server. curl -fsSL https://install.villagesql.com | bash That gets you a stable server. Please note the vector work highlighted below runs on an unmerged, development build. Declaring a vector index With the server up, the demo installs the vsql-vector extension with an ordinary INSTALL EXTENSION , and then creates one table: CREATE TABLE demo vectors id INT PRIMARY KEY, embedding SVECTOR 3 NOT NULL, INDEX idx embedding embedding hnsw l2 USING EXTENDED hnsw ENGINE=InnoDB; USING EXTENDED hnsw names a custom index type and SVECTOR is a custom column type. The extension supplies both. The server stores the metadata, plans the query, and hands the work off. Once the table exists, the vectors arrive by plain INSERT . Does the server use it? You can ask the server whether it will really use that index: EXPLAIN FORMAT=TREE SELECT id FROM demo vectors ORDER BY l2 distance embedding, ' 1.0,2.0,3.0 ' LIMIT 3\G The plan comes back as Custom index distance scan on idx embedding , which is the server saying it would answer from the HNSW graph instead of reading every row. Running that same SELECT without EXPLAIN in front of it returns the three nearest rows, closest first. Fast and correct The demo then builds two tables that hold the same 20,000 vectors. One table has an HNSW index on the vector column and the other has no index at all, and the same nearest-neighbor query runs against both. Across 50 queries each, the indexed table averages 0.19 ms and the full scan 3.82 ms, which is 20x slower. This is synthetic data at 3 dimensions, so read it as a mechanism check rather than a benchmark. Speed alone does not prove an index is beneficial, because an approximate index can be fast by being wrong. The unindexed table holds the same vectors, so it gives the exact answer to compare against. Here the index returns nine of the true top ten, and the tenth row is the price of an approximate search. ef search is a dial that allows you to tune accuracy and performance. Where it lands on real embeddings We ran ann-benchmarks against fashion-mnist-784 on an 8 vCPU Xeon VM. Below are our initial results. When vector indexes are merged, we’ll publish steps to reproduce these benchmark results. fashion-mnist-784 — 60,000 vectors, k=10, 8 vCPU Xeon | ef search | queries/sec | recall@10 | |---|---|---| | 50 | 635 | 99.68% | | 100 | 440 | 99.85% | | 200 | 290 | 99.92% | These numbers are a snapshot of the work which is still in progress. They come from one early build, and we expect them to move. The shape of the curve is the interesting part. Each step up in ef search buys recall and costs throughput. Going from 50 to 100 adds 0.17 points of recall and gives up about 30% of the queries per second. Going to 200 adds another 0.07 points and costs about half. You can choose the point on that curve that your application needs. How it fits together The server treats the extension's index as a real one. Ask what indexes a table has, and the vector ones come back as HNSW , sitting next to an ordinary BTREE . SHOW CREATE TABLE from a different example table with two vector columns returns the full definition: KEY idx title title vec vsql vector . hnsw cosine USING EXTENDED vsql vector . hnsw WITH ef construction = 64, m = 8 , KEY idx body body vec vsql vector . hnsw l1 , KEY idx tag tag M and ef construction are the extension's own build knobs. The server stores them without knowing what they mean, and prints them back in DDL you can replay. The vectors themselves sit in InnoDB's own storage, so there's no shadow table and no second write on insert. Columns go up to 3,072 dimensions for comparison, pgvector supports 2,000 dimensions for an indexed column , and one table can carry several vector indexes, each on its own column with its own distance function. What's next Filtered search, deletes, wider version coverage, and comparison benchmarks are all still ahead. We expect to deliver the custom index framework for both 8.4 and 9.7 codebases. This is an initial build of unreleased work, and we wanted to show it while it's still moving. If you want to read the code in the meantime, the extension is at github.com/villagesql/vsql-vector https://github.com/villagesql/vsql-vector , and you can get the server from villagesql.com https://villagesql.com/ . VillageSQL Server supports MySQL 8.4, 9.7, and Percona Server 8.4. Please let us know your feedback. You can find us on Discord https://discord.gg/KSr6whd3Fr or on GitHub Issues https://github.com/villagesql/villagesql-server/issues .