Select 行基于两列的长列表
Select rows based on long list of two columns
假设我有以下 table
CREATE TABLE IF NOT EXISTS "PROPS" (
"O_TYPE_ID" UUID NOT NULL,
"O_ID" UUID NOT NULL,
"R_TYPE_ID" UUID NOT NULL,
"NAME" VARCHAR NOT NULL,
"VALUE" VARCHAR,
CONSTRAINT PK_PROPS PRIMARY KEY ("O_ID", "R_TYPE_ID", "NAME")
);
现在我有了一个列表列表,它是我想用来查询 Postgres 的列表。意思是我有一个列表
List((O_ID.type, NAME.type))
我想列出所有具有这两种类型组合的记录,单个列表我可以使用 IN 运算符,在上述情况下如何查询列表 os 列表值?一个天真的实现是用两个相等子句和 and 运算符做一个 where ,但在我的例子中,如果列表太大意味着太多的 IO,你如何处理这个场景来处理列表的列表没有太多 IO 的优化方式。使用 9.4+ Postgres.
许多可能的方法之一:传递两个数组,一个 O_ID
数组(我们将其命名为 o_id_arr
),一个 NAME
数组(我们将其命名为 name_arr
);然后并行取消嵌套并加入:
SELECT p.*
FROM (o_id_arr, name_arr) AS t("O_ID", "NAME")
JOIN "PROPS" p USING ("O_ID", "NAME");
并行取消嵌套多个数组的功能是 Postgres 9.4 引入的,因此应该适合您:
或者,特别是对于大 table 和非常长的列表,创建一个临时 table,将您的数据插入其中,可选地 ANALYZE
,然后加入它:
CREATE TEMP TABLE tmp ("O_ID" UUID, "NAME" VARCHAR);
INSERT INTO tmp VALUES (..., ...), (..., ...);
ANALYZE tmp;
SELECT p.*
FROM tmp
JOIN "PROPS" p USING ("O_ID", "NAME")
通常您应该在 "PROPS" ("O_ID", "NAME")
上有一个多列索引以提高性能。但是看到 "O_ID"
是类型 uuid
,("O_ID", "R_TYPE_ID", "NAME")
上的奇数 PK 索引可能会完成这项工作。为什么 "odd"?两个 UUID 和一个 varchar 列似乎太臃肿了,无法进行良好的 PK ...
相关:
- Display one row per search term, subsitute default if not found
- Pass array literal to PostgreSQL function
旁白:摆脱那些乏味且容易出错的双引号标识符。使用不带双引号的合法小写标识符。参见:
- Are PostgreSQL column names case-sensitive?
您未加引号的约束名称 PK_PROPS
保存为 pk_props
...
假设我有以下 table
CREATE TABLE IF NOT EXISTS "PROPS" (
"O_TYPE_ID" UUID NOT NULL,
"O_ID" UUID NOT NULL,
"R_TYPE_ID" UUID NOT NULL,
"NAME" VARCHAR NOT NULL,
"VALUE" VARCHAR,
CONSTRAINT PK_PROPS PRIMARY KEY ("O_ID", "R_TYPE_ID", "NAME")
);
现在我有了一个列表列表,它是我想用来查询 Postgres 的列表。意思是我有一个列表
List((O_ID.type, NAME.type))
我想列出所有具有这两种类型组合的记录,单个列表我可以使用 IN 运算符,在上述情况下如何查询列表 os 列表值?一个天真的实现是用两个相等子句和 and 运算符做一个 where ,但在我的例子中,如果列表太大意味着太多的 IO,你如何处理这个场景来处理列表的列表没有太多 IO 的优化方式。使用 9.4+ Postgres.
许多可能的方法之一:传递两个数组,一个 O_ID
数组(我们将其命名为 o_id_arr
),一个 NAME
数组(我们将其命名为 name_arr
);然后并行取消嵌套并加入:
SELECT p.*
FROM (o_id_arr, name_arr) AS t("O_ID", "NAME")
JOIN "PROPS" p USING ("O_ID", "NAME");
并行取消嵌套多个数组的功能是 Postgres 9.4 引入的,因此应该适合您:
或者,特别是对于大 table 和非常长的列表,创建一个临时 table,将您的数据插入其中,可选地 ANALYZE
,然后加入它:
CREATE TEMP TABLE tmp ("O_ID" UUID, "NAME" VARCHAR);
INSERT INTO tmp VALUES (..., ...), (..., ...);
ANALYZE tmp;
SELECT p.*
FROM tmp
JOIN "PROPS" p USING ("O_ID", "NAME")
通常您应该在 "PROPS" ("O_ID", "NAME")
上有一个多列索引以提高性能。但是看到 "O_ID"
是类型 uuid
,("O_ID", "R_TYPE_ID", "NAME")
上的奇数 PK 索引可能会完成这项工作。为什么 "odd"?两个 UUID 和一个 varchar 列似乎太臃肿了,无法进行良好的 PK ...
相关:
- Display one row per search term, subsitute default if not found
- Pass array literal to PostgreSQL function
旁白:摆脱那些乏味且容易出错的双引号标识符。使用不带双引号的合法小写标识符。参见:
- Are PostgreSQL column names case-sensitive?
您未加引号的约束名称 PK_PROPS
保存为 pk_props
...