数据库

OrioleDB 概述


OrioleDB Postgres 扩展提供了一种可替代默认堆存储方法的存储引擎。它旨在提升 PostgreSQL 的可扩展性和性能。

OrioleDB 通过消除高并发下共享内存缓存的瓶颈,解决了 PostgreSQL 的可扩展性限制。它还通过行级 WAL 日志优化了预写日志(WAL)插入。这些改进使得在模拟真实事务工作负载的行业标准 TPC-C 基准测试中表现显著提升。以下基准测试在 c7g.metal 实例上运行,显示 OrioleDB 性能优于默认的 Postgres 堆方法,速度提升了 3.3 倍。

核心概念

索引组织表

OrioleDB 使用索引组织表,其中表数据存储在索引结构中。这种设计消除了对单独堆存储的需求,减少了开销并提高了主键查询的查找性能。

无缓冲映射

内存页通过直接链接与存储页相连。这使得 OrioleDB 能够绕过 PostgreSQL 的共享缓冲池,消除了缓冲映射相关的复杂性和争用问题。

撤销日志

多版本并发控制(MVCC)通过撤销日志实现。撤销日志存储先前行版本和事务信息,既保证了读取一致性,又完全消除了表空间整理(vacuuming)的需求。

写时复制检查点

OrioleDB采用写时复制检查点技术高效持久化数据。该方法在检查点期间仅写入修改过的数据,相比传统Postgres检查点机制减少了I/O开销,并支持行级WAL日志记录。

使用指南

创建OrioleDB项目

您可以通过在Supabase仪表板中启用扩展来开始使用OrioleDB。 要开始使用OrioleDB,您需要创建新的Supabase项目并选择OrioleDB Public Alpha作为Postgres版本。

创建数据表

要使用OrioleDB存储引擎创建表,只需执行标准的CREATE TABLE语句。默认情况下将使用OrioleDB存储引擎创建表。例如:

1
2
3
4
5
6
7
8
9
10
-- 创建数据表create table blog_post ( id int8 not null, title text not null, body text not null, author text not null, published_at timestamptz not null default CURRENT_TIMESTAMP, views bigint not null, primary key (id));

创建索引

OrioleDB 表始终拥有一个主键。如果未显式定义,系统会使用 ctid 列创建一个隐藏主键。 此外,您还可以创建二级索引。

1
2
3
4
-- 创建索引create index blog_post_published_at on blog_post (published_at);create index blog_post_views on blog_post (views) where (views > 1000);

数据操作

您可以使用标准 SQL 语句查询和修改 OrioleDB 表中的数据,包括 SELECTINSERTUPDATEDELETEINSERT ... ON CONFLICT

1
2
3
4
5
6
7
INSERT INTO blog_post (id, title, body, author, views)VALUES (1, 'Hello, World!', 'This is my first blog post.', 'John Doe', 1000);SELECT * FROM blog_post ORDER BY published_at DESC LIMIT 10; id │ title │ body │ author │ published_at │ views────┼───────────────┼─────────────────────────────┼──────────┼───────────────────────────────┼─────── 1 │ Hello, World! │ This is my first blog post. │ John Doe │ 2024-11-15 12:04:18.756824+011000

查看查询计划

您可以使用标准的 EXPLAIN 语句查看执行计划。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
EXPLAIN SELECT * FROM blog_post ORDER BY published_at DESC LIMIT 10; QUERY PLAN──────────────────────────────────────────────────────────────────────────────────────────────────────────── Limit (cost=0.15..1.67 rows=10 width=120) -> Index Scan Backward using blog_post_published_at on blog_post (cost=0.15..48.95 rows=320 width=120)EXPLAIN SELECT * FROM blog_post WHERE id = 1; QUERY PLAN────────────────────────────────────────────────────────────────────────────────── Index Scan using blog_post_pkey on blog_post (cost=0.15..8.17 rows=1 width=120) Index Cond: (id = 1)EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM blog_post ORDER BY published_at DESC LIMIT 10; QUERY PLAN────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Limit (cost=0.15..1.67 rows=10 width=120) (actual time=0.052..0.054 rows=1 loops=1) -> Index Scan Backward using blog_post_published_at on blog_post (cost=0.15..48.95 rows=320 width=120) (actual time=0.050..0.052 rows=1 loops=1) Planning Time: 0.186 ms Execution Time: 0.088 ms

相关资源