Postgresql
將日期時間拆分為餐廳預訂模式的 2 列?
使用 PostgreSQL。
其主要驅動因素是,雖然沒有日期和時間就不會存在預訂,但使用者可以使用時間或日期或兩者來搜尋和監控預訂。使用單個列,我將不斷地不得不將其分解並通過搜尋
date_trunc
。雖然 PostgreSQL 允許基於函式創建索引,但
explain
表明這並未用於使用date_trunc
.桌子:
development2=# \d reservations Table "public.reservations" Column | Type | Modifiers -----------------+-----------------------------+----------------------------------------------------------- id | integer | not null default nextval('reservations_id_seq'::regclass) tops | integer | not null price | numeric | state | integer | not null restaurant_id | integer | not null seller_id | integer | customer_id | integer | created_at | timestamp without time zone | not null start | timestamp without time zone | Indexes: "reservations_pkey" PRIMARY KEY, btree (id) "start_date_index" btree (date_trunc('day'::text, start)) Foreign-key constraints: "reservations_customer_id_fk" FOREIGN KEY (customer_id) REFERENCES users(id) "reservations_restaurant_id_fk" FOREIGN KEY (restaurant_id) REFERENCES restaurants(id) "reservations_seller_id_fk" FOREIGN KEY (seller_id) REFERENCES users(id)
詢問:
development2=# explain select id,start from reservations where date_trunc('day', start) = '2014-03-14'; QUERY PLAN ------------------------------------------------------------------------------------------------- Seq Scan on reservations (cost=0.00..1.01 rows=1 width=12) Filter: (date_trunc('day'::text, start) = '2014-03-14 00:00:00'::timestamp without time zone) (2 rows
)
甚至不知道如何進行時間搜尋,
to_char
+IMMUTABLE
我猜……
timestamp
與date
和time
如果您對時間戳的日期部分感興趣,則直接轉換它會更便宜。結果是一個實際的
date
,而date_trunc()
返回一個timestamp
!(您可以date
依次將其轉換為,但不要打擾。)您的索引應該是:CREATE INDEX start_date_index ON reservations (cast(start AS date));
cast(column AS type)
在索引定義中使用更詳細的標準表示法。在這種情況下,Postgres 速記將需要一組額外的括號:(column::type)
. 您仍然可以在查詢中使用任何一種表示法來匹配:SELECT id, start FROM reservations WHERE start::date = '2014-03-14';
看:
start::time
如果需要,您可以做類似的事情。無論哪種方式,我當然不會拆分日期和時間部分。時間戳幾乎總是出眾的設計。
索引調整
根據您的實際案例,您可以將其設為多列索引,包括
id
:CREATE INDEX start_id_date_index ON reservations (cast(start AS date), id);
這將完美地服務於上述查詢,甚至可能使用僅索引掃描。而且由於您現在
date
在索引中使用實際值(4 個字節),因此額外的整數列(也是 4 個字節)非常適合性能。看:更重要的是,您還可以在
timestamp
列上使用普通索引:CREATE INDEX start_start_index ON reservations (start);
只要確保你的
WHERE
條件是“sargable”。喜歡:SELECT id, start FROM reservations WHERE start >= '2014-03-14 0:0'::timestamp WHERE start < '2014-03-15 0:0'::timestamp;
這將使用索引。
最佳解決方案取決於您所有要求的總和。此外,儘管如此,Postgres 仍可以使用您原來的、不太理想的索引。你的表中有多少行?只有少數,順序掃描總是更快,您不會看到索引掃描。