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 中做到吗?
如果是这样,应该如何设置索引(我们无法弄清楚如何设置一个兼顾三个属性的索引)?
这对于 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 万行相比,这几乎不值得一提。