最佳实践

HALO数据库——索引

D
DBA 团队
2023年10月16日

HALO 是一个功能强大的数据库,拥有许多高级特性。其中最常用的特性之一就是索引,它可以极大地提高查询效率。

什么是索引?

在数据库中,如果没有索引,每次查询都需要扫描整个表格。这会显著减慢查询速度,尤其是当数据量很大时。因此,索引是一种用于加速数据检索的数据结构,其原理类似于书籍的目录:通过记录关键词及其物理位置,实现快速定位。

HALO 支持多种类型的索引,每种索引都有其特定的适用场景和性能特征,需根据实际查询模式和数据特点选择合适的索引类型。

以下是 HALO 数据库支持的索引类型:

1. B树索引

B树索引是 HALO 中最常见、最通用的索引类型,适用于等值查询、范围查询和排序操作。

sql
-- 创建表及插入数据
CREATE TABLE student (
  id SERIAL PRIMARY KEY,
  name VARCHAR(50) NOT NULL,
  age INTEGER NOT  NULL,
  grade VARCHAR(10) NOT NULL
);

INSERT INTO student (name, age, grade)
VALUES ('Alice', 18, '高一'),
       ('Bob', 17, '高一'),
       ('Cathy', 16, '初三'),
       ('David', 15, '初二'),
       ('Emily', 14, '初一');

-- 创建 B 树索引
CREATE INDEX idx_student_id ON student (id);

2. 哈希索引

哈希索引使用哈希算法实现极快的等值查找,但不支持范围查询、排序或模糊匹配。适用于高并发的精确匹配场景,对内存和存储开销较高。

sql
CREATE INDEX idx_student_id ON student USING hash (id);

3. GIN 索引

GIN(Generalized Inverted Index,通用倒排索引)适用于数组、JSON、全文搜索等复杂数据类型的多值查询。支持 ANY、@>、&& 等操作符,但构建和维护成本较高。

sql
-- 创建表及插入数据
CREATE TABLE mytable1 (
    id SERIAL PRIMARY KEY,
    title TEXT NOT NULL,
    tags TEXT[] NOT NULL
);

INSERT INTO mytable1 (title, tags) VALUES 
('HALO GIN Index', ARRAY['HALO', 'Database', 'Index']),
('JavaScript Frameworks', ARRAY['JavaScript', 'Framework']),
('Python Web Development', ARRAY['Python', 'Web', 'Development']),
('Data Science with R', ARRAY['Data', 'Science', 'R']),
('Introduction to Docker', ARRAY['Docker']);

-- 创建 GIN 索引
CREATE INDEX mytable_tags_gin_idx ON mytable1 USING gin(tags);

-- 查询示例
SELECT * FROM mytable1 WHERE 'Database' = ANY(tags);

4. GiST 索引

GiST(Generalized Search Tree)是一种通用索引结构,适用于几何、地理、文本相似度、网络地址等复杂数据类型的近似或范围查询。

sql
CREATE TABLE locations (
  id SERIAL PRIMARY KEY,
  name VARCHAR(50),
  point GEOMETRY(Point, 4326)
);

-- 创建 GiST 索引
CREATE INDEX idx_locations_point_gist ON locations USING gist(point);

5. BRIN 索引

BRIN(Block Range Index)适用于大规模有序数据(如时间序列)。它以数据块为单位记录最小/最大值,空间占用极小,适合过滤大范围无效数据块。

sql
-- 创建表及测试数据
CREATE TABLE sales (
    id SERIAL PRIMARY KEY,
    sale_date DATE NOT NULL,
    amount NUMERIC(10, 2) NOT NULL
);

INSERT INTO sales (sale_date, amount)
VALUES ('2023-05-16', 100.00),
       ('2023-05-17', 200.00),
       ('2023-05-18', 300.00);

-- 创建 BRIN 索引
CREATE INDEX sales_date_brin_idx ON sales USING BRIN (sale_date);

-- 查询示例
SELECT sum(amount) FROM sales WHERE sale_date BETWEEN '2023-05-16' AND '2023-05-18';

6. Bloom 索引

Bloom 索引基于布隆过滤器,是一种概率型索引,用于快速排除不可能匹配的行。适用于高基数列的等值查询,可显著减少 I/O,但存在极小误报率。

sql
-- 创建测试表及数据
CREATE TABLE test_bloom (id SERIAL PRIMARY KEY, name TEXT);
INSERT INTO test_bloom(name) SELECT 'name_' || i FROM generate_series(1, 1000000) AS i;

-- 创建扩展
CREATE EXTENSION bloom;

-- 创建 Bloom 索引
CREATE INDEX test_bloom_name_bloom_idx ON test_bloom USING bloom (name);

-- 注意:Bloom 不支持 LIKE,此处仅为示意
SELECT * FROM test_bloom WHERE name = 'name_500000';

7. RUM 索引

RUM 是一种高级索引,专为全文搜索优化,支持 trigram 相似度、距离计算和高效排序。相比 GIN,RUM 能在返回结果的同时提供相关性评分和位置信息。

sql
-- 创建表及数据
CREATE TABLE t (
  id SERIAL PRIMARY KEY,
  content TEXT NOT NULL
);

INSERT INTO t (content)
VALUES ('The quick brown fox jumps over the lazy dog.'),
       ('How vexingly quick daft zebras jump!'),
       ('Jived fox nymph grabs quick waltz.'),
       ('Glib jocks quiz nymph to vex dwarf.'),
       ('Jackdaws love my big sphinx of quartz.'),
       ('Pack my box with five dozen liquor jugs.'),
       ('The five boxing wizards jump quickly.');

-- 创建扩展
CREATE EXTENSION IF NOT EXISTS pg_trgm;

-- 创建 RUM 索引
CREATE INDEX idx_t_content_rum ON t USING rum(content rum_trgm_ops);

-- 使用 % 操作符进行相似度查询(需 pg_trgm)
SELECT * FROM t WHERE content % 'search term';

以上就是 HALO 数据库支持的主要索引类型。合理选择和组合使用这些索引,可显著提升查询性能与系统效率。


最新文章

安全公告
2025年04月11日

羲和(Halo)数据库关键补丁更新公告 - 2025年4月

安全公告
2024年06月20日

羲和(Halo)数据库关键补丁更新公告 - 2024年6月

安全公告
2023年12月18日

羲和(Halo)数据库关键补丁更新公告 - 2023年12月