使用数组列的内部连接

Chr*_*row 4 postgresql performance index gin-index query-performance

无法O (log n)及时索引和执行查询。

该查询包括一个INNER JOIN、一个ORDER BY和一个相等运算。如果我正确理解了数据库的规律,O (log n)如果一个非等式运算符没有在多于一列上使用,则可以及时(或大约)索引和执行查询。在这种情况下,我相信INNER JOIN确实算作相等运算符,而非相等运算符将是ORDER BY查询的一部分。该表有超过 10,000,000 行,需要每秒处理多次读取和写入。

使用 PostgreSQL。这就是桌子的样子。如您所见,“Names”列是一个列表属性,它是与之相反的列INNER JOIN

Age Names                       Date
34  ['carla', 'john', 'sam']    3/13/2011
26  ['json', 'cindy', 'joel']   3/13/2011
72  ['beth', 'amber', 'susie']  3/13/2011
14  ['john', 'jim', 'debie']    3/13/2011
Run Code Online (Sandbox Code Playgroud)

这是我们尝试执行的查询:

SELECT * FROM the_table WHERE Age==26 AND Names=='john' ORDER BY Date
Run Code Online (Sandbox Code Playgroud)

我的背景来自使用 App Engine 的 Big Table,所以我在这里使用了相等运算符来指示它'john'应该是Names列中的名称之一。这将是 GAE 大表中可接受的查询,它将O (log N)及时执行,因为所有大表查询都需要执行。我假设在 PostgreSQL 中也有一种方法可以做到这一点,因为 PostgreSQL 接受列表数据类型作为列。

这可以在 PostgreSQL 中做到吗?

如果是这样,应该如何设置索引(我们无法弄清楚如何设置一个兼顾三个属性的索引)?

Erw*_*ter 6

这对于 PostgreSQL 8.4 或更高版本是可能的。为了创建多列 GIN 索引,您需要安装附加模块btree_gin
简单类型(如integer或 )date通常最好使用(默认)B 树索引,因此标准 PostgreSQL 不会安装它。但是对于这种情况,多列索引是最快的,因此您需要为普通类型添加额外的索引方法。

在 PostgreSQL 9.1 或更高版本中,您可以使用以下命令安装它CREATE EXTENSION

CREATE EXTENSION btree_gin;
Run Code Online (Sandbox Code Playgroud)

在旧版本中,您将以特权系统用户身份运行(如 postgres):

CREATE EXTENSION btree_gin;
Run Code Online (Sandbox Code Playgroud)

对于 Debian 上的 PostgreSQL 8.4 安装,这可能是:

psql -d dbname -f SHAREDIR/contrib/btree_gin.sql
Run Code Online (Sandbox Code Playgroud)

然后,给定这张表:

CREATE TEMP TABLE tbl (age int, names text[], thedate date);
Run Code Online (Sandbox Code Playgroud)

...您可以创建这个多列 GIN 索引:

CREATE INDEX tbl_gin_idx ON tbl USING GIN (names, age, thedate);
Run Code Online (Sandbox Code Playgroud)

... 可用于以下查询:

SELECT * FROM tbl
WHERE  age = 26
AND    '{json}'::text[] <@ names
ORDER  BY thedate;
Run Code Online (Sandbox Code Playgroud)

请注意,GIN 索引会带来写入操作的非平凡成本。
但与SELECT没有索引的 1000 万行相比,这几乎不值得一提。