PostgreSQL 是否实现多 table 索引?

Does PostgreSQL implement multi-table indexes?

我已经搜索了一个星期了,恐怕[还]不存在。我想在 PostgreSQL 中使用跨越多个 table 的索引。 Oracle 和 SQL 服务器似乎实现了它们(有或多或少的选项)。

它对我需要执行的某些搜索非常有用。

供参考,这里是 Oracle 和 SQL 服务器的 multi-table index 示例:

Oracle 示例

Oracle可以创建位图连接索引,如下图:

create table dealer (
  id int primary key not null,
  city varchar2(20) not null
);

create table car (
  id int primary key not null,
  brand varchar2(20),
  price int,
  dealer_id int references dealer (id)
);

create bitmap index bix1 on car (d.city, c.brand)
from car c, dealer d
where d.id = c.dealer_id;

select avg(c.price)
from dealer d
join car c on c.dealer_id = d.id
where d.city = 'Chicago' and c.brand = 'Buick';

SQL 服务器示例

SQL 服务器可以创建 索引视图:

create table dealer (
  id int primary key not null,
  city varchar(20) not null
);

create table car (
  id int primary key not null,
  brand varchar(20),
  price int,
  dealer_id int references dealer (id)
);

create view v with schemabinding as
select d.city, c.brand, c.price, c.dealer_id
from dbo.dealer d
join dbo.car c on c.dealer_id = d.id;

create unique clustered index uix1 on v (city, brand, price);

select avg(c.price)
from dealer d
join car c on c.dealer_id = d.id
where d.city = 'Chicago' and c.brand = 'Buick';

从当前版本的 PostgreSQL (v 12) 开始,索引只能基于 table 或物化视图。

https://www.postgresql.org/docs/current/sql-createindex.html

CREATE INDEX constructs an index on the specified column(s) of the specified relation, which can be a table or a materialized view.

CREATE INDEX 语法需要一个 table,并且只能指定 1 个 table

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] name ] ON [ ONLY ] table_name [ USING method ]

table_name:
The name (possibly schema-qualified) of the table to be indexed.

物化视图是一个选项,但是,在您刷新数据之前,物化视图中的数据是陈旧的。

https://www.postgresql.org/docs/12/sql-creatematerializedview.html

CREATE MATERIALIZED VIEW defines a materialized view of a query. The query is executed and used to populate the view at the time the command is issued (unless WITH NO DATA is used) and may be refreshed later using REFRESH MATERIALIZED VIEW.

您也许可以通过自动执行 运行 REFRESH MATERIALIZED VIEW 命令的过程来平衡它,以减少过时数据的可能性。比如大数据导入后,其他时间间隔固定。但是,如果您的数据大到需要索引,刷新 & re-indexing 过程将不够快,因此您将无法在 OLTP 场景中的每个 CRUD 语句后执行它。

总之,从 v 12 开始,您正在寻找的内容在 PostgreSQL 中不存在。