Compare commits

...

8 Commits

Author SHA1 Message Date
Andrew Kane
54870b9bdc Debug [skip ci] 2023-03-25 16:04:48 -07:00
Andrew Kane
0950968c11 Started support for parallel index scan [skip ci] 2023-03-25 15:51:59 -07:00
Andrew Kane
ec12d79cbc Added link to pgvector-perl [skip ci] 2023-03-23 21:42:43 -07:00
Andrew Kane
d3eb56df07 Improved tests 2023-03-22 16:35:56 -07:00
Andrew Kane
13f7aa50c3 Added Render link [skip ci] 2023-03-22 16:29:06 -07:00
Andrew Kane
81e9e72fbc Updated guidance on lists [skip ci] 2023-03-22 14:00:47 -07:00
Andrew Kane
8d95510302 Updated readme [skip ci] 2023-03-22 13:32:25 -07:00
Andrew Kane
53bb2ed0cd Updated Homebrew instructions [skip ci] 2023-03-21 13:20:57 -07:00
5 changed files with 86 additions and 19 deletions

View File

@@ -109,7 +109,10 @@ Specify the number of inverted lists (100 by default)
CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 100);
```
A [good place to start](https://github.com/facebookresearch/faiss/issues/112) is `4 * sqrt(rows)`
A lower value provides better recall at the cost of speed. A good place to start is:
- `rows / 1000` for up to 1M rows
- `sqrt(rows)` for over 1M rows
### Query Options
@@ -119,7 +122,7 @@ Specify the number of probes (1 by default)
SET ivfflat.probes = 1;
```
A higher value improves recall at the cost of speed, and it can be set to the number of lists for exact nearest neighbor search (at which point the planner wont use the index)
A higher value provides better recall at the cost of speed, and it can be set to the number of lists for exact nearest neighbor search (at which point the planner wont use the index)
Use `SET LOCAL` inside a transaction to set it for a single query
@@ -201,6 +204,7 @@ Java, Scala | [pgvector-java](https://github.com/pgvector/pgvector-java)
Julia | [pgvector-julia](https://github.com/pgvector/pgvector-julia)
Lua | [pgvector-lua](https://github.com/pgvector/pgvector-lua)
Node.js | [pgvector-node](https://github.com/pgvector/pgvector-node)
Perl | [pgvector-perl](https://github.com/pgvector/pgvector-perl)
PHP | [pgvector-php](https://github.com/pgvector/pgvector-php)
Python | [pgvector-python](https://github.com/pgvector/pgvector-python)
R | [pgvector-r](https://github.com/pgvector/pgvector-r)
@@ -281,7 +285,7 @@ docker build -t pgvector .
With Homebrew Postgres, you can use:
```sh
brew install pgvector/brew/pgvector
brew install pgvector
```
### PGXN
@@ -310,8 +314,9 @@ To request a new extension on other providers:
- Amazon RDS - follow the instructions on [this page](https://aws.amazon.com/rds/postgresql/faqs/)
- Google Cloud SQL - vote or comment on [this page](https://issuetracker.google.com/issues/265172065)
- DigitalOcean Managed Databases - vote or comment on [this page](https://ideas.digitalocean.com/app-framework-services/p/pgvector-extension-for-postgresql)
- Azure Database - vote or comment on [this page](https://feedback.azure.com/d365community/idea/7b423322-6189-ed11-a81b-000d3ae49307)
- DigitalOcean Managed Databases - vote or comment on [this page](https://ideas.digitalocean.com/app-framework-services/p/pgvector-extension-for-postgresql)
- Render - vote or comment on [this page](https://feedback.render.com/features/p/add-pgvector-extension-to-postgresql)
## Upgrading

View File

@@ -103,7 +103,13 @@ ivfflatcostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
if (ratio > 1)
ratio = 1;
// cost estimates for parallel workers applied outside of amcostestimate
elog(INFO, "parallel_workers = %d, parallel aware = %d", path->path.parallel_workers, path->path.parallel_aware);
costs.indexTotalCost *= ratio;
costs.numIndexPages *= ratio;
elog(INFO, "ivfflatcostestimate = %f", costs.indexTotalCost);
/* Startup cost and total cost are same */
*indexStartupCost = costs.indexTotalCost;
@@ -151,6 +157,25 @@ ivfflatvalidate(Oid opclassoid)
return true;
}
static Size
ivfflatestimateparallelscan()
{
elog(INFO, "ivfflatestimateparallelscan");
return 0;
}
static void
ivfflatinitparallelscan(void *target)
{
elog(INFO, "ivfflatinitparallelscan");
}
static void
ivfflatparallelrescan(IndexScanDesc scan)
{
elog(INFO, "ivfflatparallelrescan");
}
/*
* Define index handler
*
@@ -178,7 +203,7 @@ ivfflathandler(PG_FUNCTION_ARGS)
amroutine->amstorage = false;
amroutine->amclusterable = false;
amroutine->ampredlocks = false;
amroutine->amcanparallel = false;
amroutine->amcanparallel = true;
amroutine->amcaninclude = false;
#if PG_VERSION_NUM >= 130000
amroutine->amusemaintenanceworkmem = false; /* not used during VACUUM */
@@ -212,9 +237,9 @@ ivfflathandler(PG_FUNCTION_ARGS)
amroutine->amrestrpos = NULL;
/* Interface functions to support parallel index scans */
amroutine->amestimateparallelscan = NULL;
amroutine->aminitparallelscan = NULL;
amroutine->amparallelrescan = NULL;
amroutine->amestimateparallelscan = ivfflatestimateparallelscan;
amroutine->aminitparallelscan = ivfflatinitparallelscan;
amroutine->amparallelrescan = ivfflatparallelrescan;
PG_RETURN_POINTER(amroutine);
}

View File

@@ -22,10 +22,28 @@ SELECT round(vector_norm('[1,1]')::numeric, 5);
1.41421
(1 row)
SELECT round(l2_distance('[1,2]', '[0,0]')::numeric, 5);
round
---------
2.23607
SELECT vector_norm('[3,4]');
vector_norm
-------------
5
(1 row)
SELECT vector_norm('[0,1]');
vector_norm
-------------
1
(1 row)
SELECT l2_distance('[0,0]', '[3,4]');
l2_distance
-------------
5
(1 row)
SELECT l2_distance('[0,0]', '[0,1]');
l2_distance
-------------
1
(1 row)
SELECT l2_distance('[1,2]', '[3]');
@@ -38,10 +56,10 @@ SELECT inner_product('[1,2]', '[3,4]');
SELECT inner_product('[1,2]', '[3]');
ERROR: different vector dimensions 2 and 1
SELECT round(cosine_distance('[1,2]', '[2,4]')::numeric, 5);
round
---------
0.00000
SELECT cosine_distance('[1,2]', '[2,4]');
cosine_distance
-----------------
0
(1 row)
SELECT cosine_distance('[1,2]', '[0,0]');

View File

@@ -2,15 +2,19 @@ SELECT '[1,2,3]'::vector + '[4,5,6]';
SELECT '[1,2,3]'::vector - '[4,5,6]';
SELECT vector_dims('[1,2,3]');
SELECT round(vector_norm('[1,1]')::numeric, 5);
SELECT round(l2_distance('[1,2]', '[0,0]')::numeric, 5);
SELECT round(vector_norm('[1,1]')::numeric, 5);
SELECT vector_norm('[3,4]');
SELECT vector_norm('[0,1]');
SELECT l2_distance('[0,0]', '[3,4]');
SELECT l2_distance('[0,0]', '[0,1]');
SELECT l2_distance('[1,2]', '[3]');
SELECT inner_product('[1,2]', '[3,4]');
SELECT inner_product('[1,2]', '[3]');
SELECT round(cosine_distance('[1,2]', '[2,4]')::numeric, 5);
SELECT cosine_distance('[1,2]', '[2,4]');
SELECT cosine_distance('[1,2]', '[0,0]');
SELECT cosine_distance('[1,1]', '[1,1]');
SELECT cosine_distance('[1,1]', '[-1,-1]');

View File

@@ -0,0 +1,15 @@
-- SET force_parallel_mode = on;
SET parallel_setup_cost = 10;
SET parallel_tuple_cost = 0.001;
SET min_parallel_table_scan_size = 1;
SET min_parallel_index_scan_size = 1;
CREATE TABLE t (id integer, val vector(3));
INSERT INTO t (id, val) SELECT n, ARRAY[random(), random(), random()] FROM generate_series(1,1000000) n;
CREATE INDEX ON t USING ivfflat (val) WITH (lists = 10);
SET ivfflat.probes = 2;
EXPLAIN SELECT * FROM t ORDER BY val <-> '[0.5,0.5,0.5]' LIMIT 5;
SELECT * FROM t ORDER BY val <-> '[0.5,0.5,0.5]' LIMIT 5;
DROP TABLE t;