PolarDB for Xscale natively provides vector storage and retrieval within the MySQL ecosystem. You can use standard SQL to define vector fields, write vector data, and perform high-performance Approximate Nearest Neighbor (ANN) similarity searches with ORDER BY VEC_DISTANCE(...) LIMIT N. This is ideal for AI scenarios such as semantic search, recommendation recall, multimodal image-text retrieval, and Retrieval-Augmented Generation (RAG).
Features
The vector index is based on the industry-leading HNSW (Hierarchical Navigable Small World) algorithm and reuses InnoDB features such as transactions, persistence, crash recovery, and primary-standby replication. This lets you use a vector index just like a regular index.
A vector index quickly finds the Top-N records most similar to a target vector from a massive collection of high-dimensional vectors.
Core features
The PolarDB-X vector index offers the following core features:
|
Feature |
Description |
|
Maximum dimensions |
Supports up to 16,383 dimensions. |
|
Data types |
single-precision floating-point (float32) |
|
Distance metrics |
Euclidean distance ( |
|
Indexing algorithms |
HNSW multilayer graph structure |
|
Hardware acceleration |
Automatically uses AVX512, AVX2, or ARM NEON instruction sets to accelerate distance calculations. |
|
Transaction support |
Supports the Read Committed (RC), Repeatable Read (RR), and Serializable isolation levels. |
|
Replication and high availability |
Supports binlog replication and XA transactions to ensure data consistency between primary/secondary instances. The Enterprise Edition supports distributed transactions. |
Prerequisites
Your instance must meet the following requirements:
-
Edition: standard edition or enterprise edition.
-
Engine version: MySQL 8.0.
-
Storage node version: V2.6.0.8.4.21-20260605 or later.
Note-
For information about the instance version naming rules, see Release notes.
-
For information about how to view the version of an instance, see View and update the engine version of a PolarDB for Xscale instance.
-
-
The system automatically synchronizes writes, updates, and deletes of vector data with the base table within the same transaction. This eliminates the need for manual index maintenance, providing an experience similar to using a regular index. Capabilities vary by instance edition:
Capability
Standard edition (centralized)
Enterprise edition (distributed)
Vector storage and ANN retrieval
Supported
Supported
Primary/standby replication and high availability
Supported
Supported
Transactions
Supported
Supported
Limitations
-
storage engine: You can create vector indexes only on tables that use the InnoDB engine.
-
Number of indexes: A table can have only one vector index.
-
partitioned table : The Standard Edition does not support vector indexes on partitioned tables, but the Enterprise Edition does.
-
DDL algorithm: Creating, modifying, or dropping a vector index uses the COPY algorithm, not INPLACE. For large tables, this process can take a long time and require a long lock period. Perform these operations during off-peak hours.
-
INVISIBLE index: You cannot set a vector index as INVISIBLE.
-
Vector data constraints: The dimension of a vector must exactly match the
Nspecified inVECTOR(N)during table creation, and the vector cannot containNaNorInfvalues. -
NULL vector: A vector column can be NULL. The vector index excludes rows with a NULL vector, and these rows do not appear in search results.
-
space amplification:
UPDATE / DELETEoperations maintain the graph structure using a "mark-then-insert" method. In workloads with frequent updates or deletions, this method causes auxiliary tables to grow, which leads to space amplification and a lower recall rate. To resolve this, periodically runOPTIMIZE TABLEto rebuild the index.
Enable vector index
The vector index feature is controlled by the vidx_disabled system variable, which is set to ON (disabled) by default. For resource isolation, you must explicitly enable this feature to create and use vector indexes.
vidx_disabled is an inverted switch: ON disables the feature, and OFF enables it.
Method 1: Use the console (Recommended)
Go to the PolarDB for Xscale console. For your target cluster, navigate to the page. On the Storage Layer tab, set the vidx_disabled parameter to OFF.
Method 2: Use the CLI
-- ON = disabled, OFF = enabled
SET GLOBAL vidx_disabled = OFF;
This change applies only to new connections. You must reconnect to use the vector index feature.
Use vector indexes
Create a vector field and index
You declare a vector field with the VECTOR(dimension) data type. For example:
Standard edition
CREATE TABLE articles (
id INT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(200),
embedding VECTOR(128) -- 128-dimensional vector field
) ENGINE=InnoDB;
Enterprise edition
CREATE TABLE articles (
id INT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(200),
embedding VECTOR(128) -- 128-dimensional vector field
) ENGINE=InnoDB
PARTITION BY KEY(id);
Create a vector index
-
Method 1: Create the index when you create the table.
Standard edition
CREATE TABLE articles ( id INT PRIMARY KEY AUTO_INCREMENT, title VARCHAR(200), embedding VECTOR(128), VECTOR INDEX vi (embedding) M=6 DISTANCE=EUCLIDEAN ) ENGINE=InnoDB;Enterprise edition
CREATE TABLE articles ( id INT PRIMARY KEY AUTO_INCREMENT, title VARCHAR(200), embedding VECTOR(128), VECTOR INDEX vi (embedding) M=6 DISTANCE=EUCLIDEAN ) ENGINE=InnoDB PARTITION BY KEY(id); -
Method 2: Add the index using ALTER TABLE.
ALTER TABLE articles ADD VECTOR INDEX vi (embedding) M=16 DISTANCE=COSINE; -
Method 3: Use CREATE VECTOR INDEX.
-- Use the default parameters M=6, DISTANCE=EUCLIDEAN CREATE VECTOR INDEX vi ON articles (embedding);
Index parameters
|
Parameter |
Description |
Recommendations |
|
M |
The maximum number of neighbor connections for each node in the graph. A larger M value increases index size and write latency but improves search accuracy.
|
|
|
DISTANCE |
The distance metric.
|
|
View vector index
Vector indexes do not appear in the output of SHOW INDEX FROM <table_name>. Use SHOW CREATE TABLE instead.
-- View the index definition (the vector index is displayed as a VECTOR KEY)
SHOW CREATE TABLE articles;
Sample output:
CREATE TABLE `articles` (
`id` int NOT NULL AUTO_INCREMENT,
`title` varchar(200) DEFAULT NULL,
`embedding` vector(128) DEFAULT NULL,
PRIMARY KEY (`id`),
VECTOR INDEX `vi`(`embedding`) M=16 DISTANCE=COSINE
) ENGINE = InnoDB
Delete vector index
-- Delete a vector index
ALTER TABLE articles DROP INDEX vi;
Write and modify vector data
Use the VEC_FROMTEXT() function to convert a vector from a string to its internal format.
-
Insert a single row
INSERT INTO articles (title, embedding) VALUES ('Introduction to Deep Learning', VEC_FROMTEXT('[0.12, 0.34, 0.56, ...]')); -
Insert multiple rows
INSERT INTO articles (title, embedding) VALUES ('Article A', VEC_FROMTEXT('[0.1, 0.2, 0.3, 0.4, 0.5]')), ('Article B', VEC_FROMTEXT('[0.5, 0.4, 0.3, 0.2, 0.1]')); -
Update a vector field (the index is updated automatically)
UPDATE articles SET embedding = VEC_FROMTEXT('[0.9, 0.8, ...]') WHERE id = 1; -
Delete a row (the index is cleaned up automatically)
DELETE FROM articles WHERE id = 1;
Vector search
-
The standard query pattern is
ORDER BY VEC_DISTANCE(...) LIMIT N:-- Find the 10 records most similar to the target vector SELECT id, title, VEC_DISTANCE(embedding, VEC_FROMTEXT('[0.1, 0.2, 0.3, 0.4, 0.5]')) AS distance FROM articles ORDER BY distance LIMIT 10;Sample output:
+----+-----------------------------+----------+------------------------+ | id | name | category | distance | +----+-----------------------------+----------+------------------------+ | 2 | Noise-canceling headphones | Digital | 0.005887877200042468 | | 1 | Wireless Bluetooth headphones| Digital | 0.006059869516314431 | | 3 | Sports Bluetooth headphones | Sports | 0.09631679001555782 | +----+-----------------------------+----------+------------------------+Optimizer behavior
-
When the optimizer detects the
ORDER BY VEC_DISTANCE(...) LIMIT Npattern, it automatically selects the vector index based on cost. -
The query must include a
LIMITclause. Otherwise, the optimizer does not use the vector index. -
If the
LIMITvalue is too large (more than 1/4 of the table rows), the optimizer falls back to a full table scan. If a query on a large table unexpectedly falls back, you can useFORCE INDEX(vector_index_name)to force the use of the vector index.
-
-
Use a
hintto force the use of an index:-- Force the use of the vector index SELECT * FROM articles FORCE INDEX(vi) ORDER BY VEC_DISTANCE_EUCLIDEAN(embedding, VEC_FROMTEXT('[0.1, 0.2, 0.3, 0.4, 0.5]')) LIMIT 10; -- Force a full table scan (for exact calculation to verify the recall rate) SELECT * FROM articles FORCE INDEX(PRIMARY) ORDER BY VEC_DISTANCE_EUCLIDEAN(embedding, VEC_FROMTEXT('[0.1, 0.2, 0.3, 0.4, 0.5]')) LIMIT 10; -
Use
EXPLAINto confirm whether the query uses a vector index. If it does, thekeycolumn shows the vector index name:EXPLAIN SELECT * FROM articles ORDER BY VEC_DISTANCE(embedding, VEC_FROMTEXT('[0.1, 0.2, 0.3, 0.4, 0.5]')) LIMIT 10;NotePolarDB-X uses a distributed execution plan format. If the query uses a vector index, the
keyfield in thephysicalPlanshows the vector index name, such asvi_embedding. If the table is small (for example, fewer than a few hundred rows), the optimizer may choose a full table scan (key:null).
Vector functions
|
Function |
Alias |
Description |
|
|
- |
Converts a string in the format |
|
|
- |
Converts a vector to a readable string. |
|
|
- |
Calculates the distance between two vectors. If v1 is an indexed column, the function automatically uses the distance type of the index. |
|
|
- |
Explicitly calculates the Euclidean distance (L2). |
|
|
- |
Explicitly calculates the cosine distance (1 − cosine similarity). |
Use VEC_DISTANCE() for routine queries. It has the simplest syntax and automatically uses the distance type of the index. Cosine distance is returned as 1 − cosine similarity, so smaller values indicate greater similarity. This behavior is consistent with Euclidean distance, allowing you to sort both in ascending order with ORDER BY distance.
System variables and parameter tuning
|
Parameter |
Scope |
Description |
|
|
GLOBAL |
A global toggle for the vector index feature. Changes take effect after you reconnect.
|
|
|
SESSION |
The default distance metric used when you create an index without specifying the
Note
This parameter can be modified only on the Parameter Settings page in the console. The SQL |
|
|
SESSION |
The default value for the
Note
This parameter can be modified only on the Parameter Settings page in the console. The SQL |
|
|
SESSION |
Specifies the size of the candidate set during a search. A larger value improves accuracy but increases latency. This value cannot be smaller than the
|
|
|
GLOBAL |
The maximum memory cache size for a single vector index.
Note
This parameter can be modified only on the Parameter Settings page in the console. The SQL |
ef_search selection
|
|
Expected recall rate |
Applicable scenarios |
|
10 |
~85% |
For latency-sensitive scenarios where a slightly lower recall rate is acceptable. |
|
20 (default) |
~92% |
Offers a good balance between recall rate and latency. |
|
50–100 |
~97% |
High-accuracy scenarios. |
|
200+ |
~99%+ |
Approaches the accuracy of a brute-force search. |
Tuning examples
-- Trade latency for higher accuracy
SET SESSION vidx_hnsw_ef_search = 100;
-- Trade accuracy for lower latency
SET SESSION vidx_hnsw_ef_search = 10;
Monitoring and O&M
Run the following command to view the runtime status of vector indexes:
SHOW GLOBAL STATUS LIKE 'Vidx%';
Sample output:
+----------------------------------+----------+
| Variable_name | Value |
+----------------------------------+----------+
| Vidx_cache_usage | 1048576 |
| Vidx_insert_count | 5 |
| Vidx_load_node_hits | 14 |
| Vidx_load_node_misses | 10 |
| Vidx_load_vec_hits | 6 |
| Vidx_load_vec_misses | 6 |
| Vidx_query_count | 1 |
| Vidx_update_count | 0 |
| ... | ... |
+----------------------------------+----------+
Common monitoring metrics
|
Parameter |
Description |
|
|
Total number of vector queries. |
|
|
Total number of vector inserts and updates. |
|
|
Number of graph node cache hits and misses. |
|
|
Number of vector data cache hits and misses. |
|
|
Current cache memory usage in bytes. |
O&M suggestions
-
Cache hit rate =
(Vidx_load_node_hits + Vidx_load_vec_hits) / (Vidx_load_node_hits + Vidx_load_node_misses + Vidx_load_vec_hits + Vidx_load_vec_misses). If the cache hit rate is lower than 90%, you can increase the value ofvidx_hnsw_cache_size. -
Regularly running
OPTIMIZE TABLEcleans up redundant nodes created by updates and deletions and controls space growth. -
For high-precision requirements, prioritize increasing the value of
vidx_hnsw_ef_search, and ensure that it is greater than or equal to theLIMITof the query.
End-to-end example
This example walks you through a complete product semantic search workflow:
-
Enable the feature
SET GLOBAL vidx_disabled = OFF; -
Create a table and define a 5-dimensional vector field
Standard edition
CREATE TABLE products ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100) NOT NULL, category VARCHAR(50), embedding VECTOR(5) ) ENGINE=InnoDB;Enterprise edition
CREATE TABLE products ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100) NOT NULL, category VARCHAR(50), embedding VECTOR(5) ) ENGINE=InnoDB PARTITION BY KEY(id); -
Create a vector index (cosine distance)
ALTER TABLE products ADD VECTOR INDEX vi_embedding (embedding) M=6 DISTANCE=COSINE; -
Insert product data
INSERT INTO products (name, category, embedding) VALUES ('Wireless Bluetooth earbuds', 'Electronics', VEC_FROMTEXT('[0.8, 0.1, 0.3, 0.5, 0.2]')), ('Noise-canceling over-ear headphones', 'Electronics', VEC_FROMTEXT('[0.7, 0.2, 0.4, 0.6, 0.1]')), ('Sports Bluetooth earbuds', 'Sports', VEC_FROMTEXT('[0.6, 0.5, 0.3, 0.4, 0.3]')), ('Smartwatch', 'Electronics', VEC_FROMTEXT('[0.3, 0.7, 0.2, 0.8, 0.1]')); -
Retrieve the three most similar products to "Bluetooth earbuds"
SELECT id, name, category, VEC_DISTANCE(embedding, VEC_FROMTEXT('[0.75, 0.15, 0.35, 0.55, 0.15]')) AS distance FROM products ORDER BY distance LIMIT 3;Example output:
+----+---------------------------------------+-------------+------------------------+ | id | name | category | distance | +----+---------------------------------------+-------------+------------------------+ | 2 | Noise-canceling over-ear headphones | Electronics | 0.005887877200042468 | | 1 | Wireless Bluetooth earbuds | Electronics | 0.006059869516314431 | | 3 | Sports Bluetooth earbuds | Sports | 0.09631679001555782 | +----+---------------------------------------+-------------+------------------------+
FAQ
-
Confirming vector index support and status
Verify that your instance's storage node version is V2.6.0.8.4.21-20260605 or later. Then, run the following command to check if the feature is enabled. The feature is enabled if the command returns a value of
OFF.SHOW GLOBAL VARIABLES LIKE 'vidx_disabled';Sample output:
+-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | vidx_disabled | OFF | +-----------------+-------+ -
Vector index not used in search
Check the following conditions in order:
-
vidx_disabled = OFFand you have re-established the connection. -
The SQL query includes an
ORDER BY VEC_DISTANCE(...) LIMIT Nclause. -
The
LIMITvalue does not exceed 1/4 of the table's row count.
You can verify this by using
EXPLAIN. If a query uses the vector index, its name appears in thekeycolumn. -
-
Low search recall rate
You can increase the
vidx_hnsw_ef_searchsession variable (for example, to a value between 50 and 100) or increase theMparameter (for example, to 16) when you create the index. To establish a baseline for comparison, you can perform an exact search by forcing a full table scan withFORCE INDEX(PRIMARY). -
Why is creating a vector index slow?
Vector index creation uses the COPY algorithm to create an HNSW graph structure for each existing data entry. This process can be time-consuming for large tables. Perform this operation during off-peak hours to avoid performance degradation.
-
Vector index storage and memory requirements
-
Storage: The vector index size is approximately 1.5 times the size of the vector column in the base table.
-
Memory: The
vidx_hnsw_cache_sizeparameter controls the maximum cache size for a single index. -
Cache: The cache size is primarily determined by the row count, vector dimension, and
Mparameter. You can estimate the required size (in bytes) by using the following rule of thumb:vidx_hnsw_cache_size ≈ row count × (dimension × 2 + M × 16 + 60)-
dimension × 2: The size of the vector after quantization and compression (2 bytes per dimension). -
M × 16: The overhead for storing neighbor connections for each graph node. -
60: Fixed overhead for node objects and other metadata.
Estimation examples:
Row count
Dimension
M
Recommended cache
1,000,000
128
6
≈ 412 MB
1,000,000
768
16
≈ 1.8 GB
10,000,000
128
6
≈ 4.1 GB
-
NoteExceeding the cache limit triggers a full rebuild and can impact query performance. Set the cache size slightly higher than the estimated value. If monitoring shows a low cache hit rate, increase the size further.
-
-
Vector index support for replication and HA
Yes. Vector data writes synchronize with the base table within the same transaction and are replicated to the replica database via binlog, ensuring data consistency between the primary and replica instances. The vector index feature also supports XA transactions. In the Enterprise Edition (Distributed), the vector index also supports distributed transactions, ensuring consistency for vector data writes and searches across multiple shards.