Postgresql
減小數據庫的大小(使用表達式索引)?
這是我在 Postgres 10.1-1 數據庫中的目前表定義:
CREATE TYPE CUSTOMER_TYPE AS ENUM ('enum1', 'enum2', 'enum3', '...', 'enum15'); -- max length of enum names ~15 CREATE TABLE CUSTOMER( CUSTOMER_ONE TEXT PRIMARY KEY NOT NULL, -- max 35 char String ATTRIBUTE_ONE TEXT UNIQUE, -- max 35 char String ATTRIBUTE_TWO TEXT, -- 1-80 char String PRIVATEKEYTYPE CUSTOMER_TYPE -- see enum );
與插入數據的大小相比,它導致數據庫大小增加約 4.3 倍。(50 MB,700.000 行 –> 數據庫大小為 210 MB)
Attribute_One
計算為hash(Customer_One)
。**要求:**快速搜尋(使用算法)列
CUSTOMER_ONE
和ATTRIBUTE_ONE
. (這就是為什麼我認為我需要一個索引。)典型的搜尋查詢:
select * from customer where Customer_One='XXX' OR Attribute_One='XXX';
每個
SELECT
可以在數百萬行中找到最多 1 個或 0 個匹配行。是否可以進一步減小數據庫大小?有人告訴我使用表達式索引,但不完全理解它是如何工作的。帶有範例索引或其他解決方案的簡短解釋會很棒
插入速度是否受這些索引的影響?越快越好。(要明確:搜尋速度比插入速度更重要。)
If
hash()
是一個IMMUTABLE
函式(對於名為“hash”的函式應該是這種情況!),您可以完全省略將函式依賴儲存attribute_one
在表中,並添加一個表達式索引以支持對錶達式的查詢hash(customer_one)
:CREATE TABLE customer ( privatekeytype customer_type -- move the enum to 1st pos to save some more , customer_one text PRIMARY KEY , attribute_two text );
表達指數:
CREATE INDEX customer_attribute_one_idx ON customer (hash(customer_one));
UNIQUE
這與支持您對冗餘列的原始約束的索引完全相同(相同)attribute_one
。詢問:
SELECT * FROM customer WHERE 'XXX' IN (customer_one, hash(customer_one));
與
EXPLAIN
您一起測試會看到索引或點陣圖索引掃描,例如:-> BitmapOr (cost=5.34..5.34 rows=5 width=0) -> Bitmap Index Scan on customer_pkey (cost=0.00..2.66 rows=1 width=0) Index Cond: ('XXX'::text = customer.customer_one) -> Bitmap Index Scan on customer_attribute_one_idx (cost=0.00..2.68 rows=4 width=0) Index Cond: ('XXX'::text = hash(customer.customer_one))
與冗餘表列的性能大致相同或更快,因為表更小,但 - 這以各種方式幫助整體性能。
移動
enum
到第一個位置可以節省每行對齊填充的幾個字節,如我之前的回答中所述:為什麼函式必須是
IMMUTABLE
?看: