Skip to content

Commit e2b5478

Browse files
committed
feat: add support for PolarDB
- add PolarDB vector search client with FAISS_HNSW_FLAT, FAISS_HNSW_PQ, and FAISS_HNSW_SQ index types - add CLI integration with hnswflat, hnswpq, and hnswsq benchmark commands - add frontend (Streamlit) UI support with index type selection, HNSW/PQ/SQ parameter configuration
1 parent cf536a9 commit e2b5478

12 files changed

Lines changed: 884 additions & 1 deletion

File tree

README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ All the database client supported
6262
| hologres | `pip install vectordb-bench[hologres]` |
6363
| tencent_es | `pip install vectordb-bench[tencent_es]` |
6464
| alisql | `pip install 'vectordb-bench[alisql]'` |
65+
| polardb | `pip install vectordb-bench[polardb]` |
6566
| doris | `pip install vectordb-bench[doris]` |
6667
| zvec | `pip install vectordb-bench[zvec]` |
6768
| endee | `pip install vectordb-bench[endee]` |
@@ -527,6 +528,47 @@ To list the options for Lindorm, execute `vectordbbench lindormhnsw --help`, The
527528
--ef-search INTEGER hnsw ef-search [required]
528529
```
529530

531+
### Run PolarDB from command line
532+
533+
PolarDB supports index types: faiss_hnsw_flat, faiss_hnsw_pq, and faiss_hnsw_sq.
534+
535+
**Example: Run faiss_hnsw_flat benchmark**
536+
537+
```shell
538+
vectordbbench polardbhnswflat \
539+
--case-type Performance768D1M \
540+
--username <db_user> \
541+
--password '<db_password>' \
542+
--host <db_host> \
543+
--port 3306 \
544+
--m 16 \
545+
--ef-construction 256 \
546+
--ef-search 256 \
547+
--insert-workers 64 \
548+
--num-concurrency '10,20,40,60,80' \
549+
--concurrency-duration 60 \
550+
--task-label <task_label> \
551+
--db-label <db_label> \
552+
--skip-search-serial \
553+
--post-load-index
554+
```
555+
556+
To list the options for PolarDB, execute `vectordbbench polardbhnswflat --help`. The following are some PolarDB-specific command-line options.
557+
558+
```text
559+
--username TEXT Username [required]
560+
--password TEXT Password
561+
--host TEXT Db host [default: 127.0.0.1]
562+
--port INTEGER Db Port [default: 3306]
563+
--database TEXT Database name [default: vectordbbench]
564+
--m INTEGER M parameter (max_degree) in HNSW
565+
--ef-construction INTEGER ef_construction parameter in HNSW
566+
--ef-search INTEGER polar_vector_index_hnsw_ef_search session variable
567+
--insert-workers INTEGER Number of concurrent threads for data insertion
568+
--post-load-index / --inline-index
569+
Create index after load or inline at table creation
570+
```
571+
530572
#### Using a configuration file.
531573

532574
The vectordbbench command can optionally read some or all the options from a yaml formatted configuration file.

install/requirements_py3.11.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,6 @@ pymilvus
2626
clickhouse_connect
2727
pyvespa
2828
mysql-connector-python
29+
PyMySQL
2930
packaging
30-
hdrhistogram>=0.10.1
31+
hdrhistogram>=0.10.1

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ vespa = [ "pyvespa" ]
106106
lancedb = [ "lancedb" ]
107107
oceanbase = [ "mysql-connector-python" ]
108108
alisql = [ "mysql-connector-python" ]
109+
polardb = [ "PyMySQL" ]
109110
doris = [ "doris-vector-search" ]
110111
turbopuffer = [ "turbopuffer" ]
111112
zvec = [ "zvec" ]

vectordb_bench/backend/clients/__init__.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class DB(Enum):
5959
Zvec = "Zvec"
6060
Endee = "Endee"
6161
Lindorm = "Lindorm"
62+
PolarDB = "PolarDB"
6263

6364
@property
6465
def init_cls(self) -> type[VectorDB]: # noqa: PLR0911, PLR0912, C901, PLR0915
@@ -246,6 +247,11 @@ def init_cls(self) -> type[VectorDB]: # noqa: PLR0911, PLR0912, C901, PLR0915
246247

247248
return LindormVector
248249

250+
if self == DB.PolarDB:
251+
from .polardb.polardb import PolarDB
252+
253+
return PolarDB
254+
249255
msg = f"Unknown DB: {self.name}"
250256
raise ValueError(msg)
251257

@@ -435,6 +441,11 @@ def config_cls(self) -> type[DBConfig]: # noqa: PLR0911, PLR0912, C901, PLR0915
435441

436442
return LindormConfig
437443

444+
if self == DB.PolarDB:
445+
from .polardb.config import PolarDBConfig
446+
447+
return PolarDBConfig
448+
438449
msg = f"Unknown DB: {self.name}"
439450
raise ValueError(msg)
440451

@@ -581,6 +592,11 @@ def case_config_cls( # noqa: C901, PLR0911, PLR0912, PLR0915
581592

582593
return AliSQLIndexConfig
583594

595+
if self == DB.PolarDB:
596+
from .polardb.config import _polardb_case_config
597+
598+
return _polardb_case_config.get(index_type)
599+
584600
if self == DB.Doris:
585601
from .doris.config import DorisCaseConfig
586602

vectordb_bench/backend/clients/polardb/__init__.py

Whitespace-only changes.
Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
from __future__ import annotations
2+
3+
from typing import TYPE_CHECKING, Annotated, Unpack
4+
5+
if TYPE_CHECKING:
6+
from .config import PolarDBConfig
7+
8+
import click
9+
from pydantic import SecretStr
10+
11+
from vectordb_bench.backend.clients import DB
12+
13+
from ....cli.cli import (
14+
CommonTypedDict,
15+
cli,
16+
click_parameter_decorators_from_typed_dict,
17+
run,
18+
)
19+
20+
21+
class PolarDBTypedDict(CommonTypedDict):
22+
user_name: Annotated[
23+
str,
24+
click.option(
25+
"--username",
26+
type=str,
27+
help="Username",
28+
required=True,
29+
),
30+
]
31+
password: Annotated[
32+
str,
33+
click.option(
34+
"--password",
35+
type=str,
36+
help="Password",
37+
default="",
38+
),
39+
]
40+
41+
host: Annotated[
42+
str,
43+
click.option(
44+
"--host",
45+
type=str,
46+
help="Db host",
47+
default="127.0.0.1",
48+
),
49+
]
50+
51+
port: Annotated[
52+
int,
53+
click.option(
54+
"--port",
55+
type=int,
56+
default=3306,
57+
help="Db Port",
58+
),
59+
]
60+
61+
database: Annotated[
62+
str,
63+
click.option(
64+
"--database",
65+
type=str,
66+
help="Database name",
67+
default="vectordbbench",
68+
),
69+
]
70+
71+
unix_socket: Annotated[
72+
str,
73+
click.option(
74+
"--unix-socket",
75+
type=str,
76+
help="Unix socket path (overrides host/port if set)",
77+
default="",
78+
),
79+
]
80+
81+
82+
class PolarDBHNSWTypedDict(PolarDBTypedDict):
83+
m: Annotated[
84+
int,
85+
click.option(
86+
"--m",
87+
type=int,
88+
help="M parameter (max_degree) in HNSW",
89+
default=16,
90+
),
91+
]
92+
93+
ef_construction: Annotated[
94+
int,
95+
click.option(
96+
"--ef-construction",
97+
type=int,
98+
help="ef_construction parameter in HNSW",
99+
default=200,
100+
),
101+
]
102+
103+
ef_search: Annotated[
104+
int,
105+
click.option(
106+
"--ef-search",
107+
type=int,
108+
help="polar_vector_index_hnsw_ef_search session variable",
109+
default=64,
110+
),
111+
]
112+
113+
insert_workers: Annotated[
114+
int,
115+
click.option(
116+
"--insert-workers",
117+
type=int,
118+
help="Number of concurrent threads for data insertion",
119+
default=10,
120+
),
121+
]
122+
123+
post_load_index: Annotated[
124+
bool,
125+
click.option(
126+
"--post-load-index/--inline-index",
127+
type=bool,
128+
help="Create vector index via ALTER TABLE after data load; "
129+
"otherwise create index inline during table creation",
130+
default=False,
131+
),
132+
]
133+
134+
135+
class PolarDBHNSWPQTypedDict(PolarDBHNSWTypedDict):
136+
pq_m: Annotated[
137+
int,
138+
click.option(
139+
"--pq-m",
140+
type=int,
141+
help="PQ subquantizer count (must divide dimension)",
142+
default=1,
143+
),
144+
]
145+
146+
pq_nbits: Annotated[
147+
int,
148+
click.option(
149+
"--pq-nbits",
150+
type=int,
151+
help="PQ bits per subquantizer (max 24)",
152+
default=8,
153+
),
154+
]
155+
156+
157+
class PolarDBHNSWSQTypedDict(PolarDBHNSWTypedDict):
158+
sq_type: Annotated[
159+
str,
160+
click.option(
161+
"--sq-type",
162+
type=str,
163+
help="SQ quantizer type (8bit, 4bit, fp16, bf16, 6bit, etc.)",
164+
default="8bit",
165+
),
166+
]
167+
168+
169+
def _build_db_config(parameters: dict) -> PolarDBConfig:
170+
from .config import PolarDBConfig
171+
172+
pwd = parameters["password"]
173+
sock = parameters["unix_socket"]
174+
return PolarDBConfig(
175+
db_label=parameters["db_label"],
176+
user_name=parameters["username"],
177+
password=SecretStr(pwd) if pwd else None,
178+
host=parameters["host"],
179+
port=parameters["port"],
180+
database=parameters["database"],
181+
unix_socket=sock if sock else None,
182+
)
183+
184+
185+
@cli.command()
186+
@click_parameter_decorators_from_typed_dict(PolarDBHNSWTypedDict)
187+
def PolarDBHNSWFlat(
188+
**parameters: Unpack[PolarDBHNSWTypedDict],
189+
):
190+
from .config import PolarDBHNSWFlatConfig
191+
192+
run(
193+
db=DB.PolarDB,
194+
db_config=_build_db_config(parameters),
195+
db_case_config=PolarDBHNSWFlatConfig(
196+
M=parameters["m"],
197+
ef_construction=parameters["ef_construction"],
198+
ef_search=parameters["ef_search"],
199+
insert_workers=parameters["insert_workers"],
200+
post_load_index=parameters["post_load_index"],
201+
),
202+
**parameters,
203+
)
204+
205+
206+
@cli.command()
207+
@click_parameter_decorators_from_typed_dict(PolarDBHNSWPQTypedDict)
208+
def PolarDBHNSWPQ(
209+
**parameters: Unpack[PolarDBHNSWPQTypedDict],
210+
):
211+
from .config import PolarDBHNSWPQConfig
212+
213+
run(
214+
db=DB.PolarDB,
215+
db_config=_build_db_config(parameters),
216+
db_case_config=PolarDBHNSWPQConfig(
217+
M=parameters["m"],
218+
ef_construction=parameters["ef_construction"],
219+
ef_search=parameters["ef_search"],
220+
insert_workers=parameters["insert_workers"],
221+
post_load_index=parameters["post_load_index"],
222+
pq_m=parameters["pq_m"],
223+
pq_nbits=parameters["pq_nbits"],
224+
),
225+
**parameters,
226+
)
227+
228+
229+
@cli.command()
230+
@click_parameter_decorators_from_typed_dict(PolarDBHNSWSQTypedDict)
231+
def PolarDBHNSWSQ(
232+
**parameters: Unpack[PolarDBHNSWSQTypedDict],
233+
):
234+
from .config import PolarDBHNSWSQConfig
235+
236+
run(
237+
db=DB.PolarDB,
238+
db_config=_build_db_config(parameters),
239+
db_case_config=PolarDBHNSWSQConfig(
240+
M=parameters["m"],
241+
ef_construction=parameters["ef_construction"],
242+
ef_search=parameters["ef_search"],
243+
insert_workers=parameters["insert_workers"],
244+
post_load_index=parameters["post_load_index"],
245+
sq_type=parameters["sq_type"],
246+
),
247+
**parameters,
248+
)

0 commit comments

Comments
 (0)