EUCLIDEAN_DISTANCE

The EUCLIDEAN_DISTANCE function returns the euclidean distance between two vector values. EUCLIDEAN_DISTANCE takes as input two vectors, and returns a numeric value.

A common use of EUCLIDEAN_DISTANCE is to calculate the similarity between vectors (vector similarity), which is used in semantic text search, generative AI, searches of images and audio files, and other applications. A typical query using EUCLIDEAN_DISTANCE is to find a set of vectors that most closely match a query vector.

See Working with Vector Data for more information about using vectors in SingleStore.

Syntax

EUCLIDEAN_DISTANCE(vector_expression, vector_expression)

Arguments

  • vector_expression: An expression that evaluates to a vector. Vectors can be stored in SingleStore using the BLOB data type (BLOB Types).

Remarks

  • If the result of EUCLIDEAN_DISTANCE() is infinity, negative infinity, or not a number (NaN), NULL will be returned instead.

  • The default format for vector element storage and processing is 32-bit floating point number (FLOAT). The EUCLIDEAN_DISTANCE function assumes the vector inputs are encoded as 32-bit floating point numbers and returns a DOUBLE.

  • EUCLIDEAN_DISTANCE(v1, v2) is computationally equivalent to SQRT(DOT_PRODUCT(VECTOR_SUB(v1, v2), VECTOR_SUB(v1, v2))). However, the EUCLIDEAN_DISTANCE() function is more efficient than the latter.

  • To execute this function, the host processor must support AVX2 instruction set extensions. If AVX2 is not supported, an error will occur during execution.

Using EUCLIDEAN_DISTANCE with Vectors as BLOBs

The following example shows the use of  EUCLIDEAN_DISTANCE() to calculate the similarity between a query vector and a set of vectors in a table with the vectors stored as BLOBs.

Create a table with a column of type BLOB to store the vectors. The second column in this table, with column name vec and type BLOB, will store the vectors. This example demonstrates storing vector data using BLOBs, hence the column of type BLOB named vec.

CREATE TABLE vectors_b (id int, vec BLOB not null);

Use the JSON_ARRAY_PACK() built-in function to easily insert properly formatted vectors.

INSERT INTO vectors_b VALUES (1, JSON_ARRAY_PACK('[0.1, 0.8, 0.2, 0.555]')); 
INSERT INTO vectors_b VALUES(2, JSON_ARRAY_PACK('[0.45, 0.55, 0.495, 0.5]'));

Use the HEX() built-in function to return a printable form of the binary data:

SELECT HEX(vec) FROM vectors_b;
+----------------------------------+
| HEX(vec)                         |
+----------------------------------+
| 6666E63ECDCC0C3FA470FD3E0000003F |
| CDCCCC3DCDCC4C3FCDCC4C3E7B140E3F |
+----------------------------------+

Query the table using the EUCLIDEAN_DISTANCE() function in a SELECT statement.

First, set up a query vector.

SET @query_vec = JSON_ARRAY_PACK('[0.44, 0.554, 0.34, 0.62]');

Now, write a query that calculates the EUCLIDEAN_DISTANCE of the query vector and vectors in the vectors_b table.

SELECT EUCLIDEAN_DISTANCE(vec, @query_vec) AS score 
FROM vectors_b;
+---------------------+
| score               |
+---------------------+
| 0.19631861943383927 |
| 0.44714763700937277 |
+---------------------+

EUCLIDEAN_DISTANCE() with JSON_ARRAY_PACK()

The JSON_ARRAY_PACK() function makes it easier to input properly-formatted vectors. JSON_ARRAY_PACK() should be used when loading vectors into tables as is shown in the example below. That is, vectors should be formatted with JSON_ARRAY_PACK() at the time they are loaded into a table so that the data stored in the BLOB attribute in the table is in packed binary format. It is not recommended to store vectors as JSON strings in tables, doing so will have a negative performance impact.

JSON_ARRAY_PACK() should not normally be used as an argument to the DOT_PRODUCT function except when JSON_ARRAY_PACK() is being used to build a constant vector value as is shown in the query below.

SELECT EUCLIDEAN_DISTANCE(                
JSON_ARRAY_PACK('[0.44, 0.554, 0.34, 0.62]'), vec) AS score
FROM vectors_b;
+---------------------+
| score               |
+---------------------+
| 0.19631861943383927 |
| 0.44714763700937277 |
+---------------------+

Using EUCLIDEAN_DISTANCE in Filters, Joins, and Ordering

EUCLIDEAN_DISTANCE can appear wherever a floating point expression can be used in a query, including in filters, ordering, joins and cross products.

Use the vectors_b table and the @query_vec created above, in addition to the new table created below, when running the following query.

The following query uses EUCLIDEAN_DISTANCE  in the SELECT clause, names it "score," and then filters on the score in the WHERE clause. Note that in contrast to the previous query, the result of this query includes both the vector and the score, or EUCLIDEAN_DISTANCE, of that vector with respect to @query_vec.

SELECT vec, EUCLIDEAN_DISTANCE(vec, @query_vec) AS score
FROM vectors_b 
WHERE score < 0.7
ORDER BY score ASC;
+---------------------------------------------------+---------------------+
| vec                                               | score               |
+---------------------------------------------------+---------------------+
| [0.449999988,0.550000012,0.495000005,0.5]         | 0.19631861943383927 |
| [0.100000001,0.800000012,0.200000003,0.555000007] | 0.44714763700937277 |
+---------------------------------------------------+---------------------+

Formatting Binary Vector Data for BLOBs

When using the BLOB data type for EUCLIDEAN_DISTANCE operations, the vector data can be formatted using JSON_ARRAY_PACK. Alternatively, if your vector data is already in a packed binary format, you can load that data into the BLOBs. The data must be encoded as a BLOB containing packed numbers in little-endian byte order. Vectors stored as BLOBs can be of any length; however, the input blob length must be divisible by the size of the packed vector elements (1, 2, 4 or 8 bytes, depending on the vector element). Vector element types listed in the table above are supported.

Last modified: March 1, 2024

Was this article helpful?