intagg
模組提供整數聚合器和枚舉器。intagg
現在已過時,因為有內建函數提供其功能的超集合。但是,該模組仍然作為內建函數的相容性包裝提供。
聚合器是一個聚合函數 int_array_aggregate(integer)
,它產生一個整數陣列,其中包含它所接收的整數。 這是 array_agg
的包裝函式,它對任何陣列類型執行相同的操作。
枚舉器是一個函數 int_array_enum(integer[])
,它返回 setof integer
。 它本質上是聚合器的反向操作:給定一個整數陣列,將其展開為一組行。 這是 unnest
的包裝函式,它對任何陣列類型執行相同的操作。
許多資料庫系統都有多對多表的概念。 這樣的表通常位於兩個索引表之間,例如
CREATE TABLE left_table (id INT PRIMARY KEY, ...); CREATE TABLE right_table (id INT PRIMARY KEY, ...); CREATE TABLE many_to_many(id_left INT REFERENCES left_table, id_right INT REFERENCES right_table);
它通常像這樣使用
SELECT right_table.*
FROM right_table JOIN many_to_many ON (right_table.id = many_to_many.id_right)
WHERE many_to_many.id_left = item
;
這將傳回左側表中條目右側表中的所有項目。 這是 SQL 中非常常見的結構。
現在,如果 many_to_many
表中有大量條目,此方法可能會很麻煩。 通常,像這樣的聯結會導致索引掃描,並為特定左側條目的表中每個右側條目提取。 如果您有一個非常動態的系統,您就無能為力。 但是,如果您有一些相當靜態的資料,則可以使用聚合器建立摘要表。
CREATE TABLE summary AS SELECT id_left, int_array_aggregate(id_right) AS rights FROM many_to_many GROUP BY id_left;
這將建立一個表,每個左側項目一行,以及一個右側項目陣列。 現在,如果沒有使用該陣列的方法,這幾乎是無用的; 這就是為什麼有一個陣列枚舉器的原因。 你可以做
SELECT id_left, int_array_enum(rights) FROM summary WHERE id_left = item
;
上述使用 int_array_enum
的查詢產生與以下查詢相同的結果
SELECT id_left, id_right FROM many_to_many WHERE id_left = item
;
不同之處在於,針對摘要表執行的查詢必須僅從表中獲取一行,而針對 many_to_many
執行的直接查詢必須為每個條目進行索引掃描並提取一行。
在一個系統上,EXPLAIN
顯示成本為 8488 的查詢已降低到成本為 329。 原始查詢是涉及 many_to_many
表的聯結,該表已替換為
SELECT id_right, count(id_right) FROM
( SELECT id_left, int_array_enum(rights) AS id_right
FROM summary
JOIN (SELECT id FROM left_table
WHERE id = item
) AS lefts
ON (summary.id_left = lefts.id)
) AS list
GROUP BY id_right
ORDER BY count DESC;
如果您在文件中發現任何不正確、與特定功能的使用經驗不符或需要進一步說明的資訊,請使用此表單回報文件問題。