PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Truy vấn múi giờ Optimize / Index

Nếu bạn thực sự có một cột thuộc loại timestamp và diễn giải nó (theo từng phần) tùy thuộc vào múi giờ hiện tại và múi giờ này có thể thay đổi, khi đó một chỉ mục nói chung là không thể . Bạn chỉ có thể tạo chỉ mục trên IMMUTABLE dữ liệu ...

Sau khi cập nhật:

Để trả lời những câu hỏi này:

  1. Đặt chỗ nào sẽ bắt đầu "hôm nay"?
  2. Đặt chỗ nào có ngày bắt đầu trong tương lai?
  3. Đặt chỗ nào có ngày bắt đầu trong quá khứ?

... tốt nhất bạn nên lưu trữ timestamp with time zone . Chỉ là một date không đủ chính xác.

Miễn là chúng tôi chỉ quan tâm đến địa phương "hôm nay" (như được xác định bởi múi giờ hiện tại ), chúng tôi không cần lưu múi giờ một cách rõ ràng. Chúng tôi không quan tâm điều đó xảy ra ở đâu trên thế giới, chúng tôi chỉ cần một khoảng thời gian tuyệt đối để so sánh với.

Sau đó, để nhận đặt chỗ bắt đầu từ "hôm nay", chỉ cần:

SELECT *
FROM   reservations
WHERE  start_on::date = current_date;

Nhưng đây là không thể phân loại bởi vì start_on::date là một biểu thức dẫn xuất và chúng tôi cũng không thể xây dựng một chỉ mục chức năng cho điều này, (không có các thủ thuật bẩn) vì biểu thức phụ thuộc vào múi giờ hiện tại và không phải là IMMUTABLE .

Thay vào đó , so sánh với thời điểm bắt đầu và kết thúc ngày của "chúng ta" theo giờ UTC:

SELECT *
FROM   reservations
WHERE  start_on >= current_date::timestamptz
AND    start_on < (current_date + 1)::timestamptz; -- exclude upper border

Bây giờ, chỉ mục đơn giản này có thể hỗ trợ truy vấn:

CREATE INDEX ON reservations (start_on);

Bản trình diễn

SQL Fiddle ngừng hoạt động ATM. Dưới đây là một bản demo nhỏ để giúp bạn hiểu:

CREATE TEMP TABLE reservations (
   reservation_id serial
 , start_on timestamptz NOT NULL
 , time_zone text);    -- we don't need this

INSERT INTO reservations (start_on, time_zone) VALUES
  ('2014-04-09 01:00+02', 'Europe/Vienna')
, ('2014-04-09 23:00+02', 'Europe/Vienna')
, ('2014-04-09 01:00+00', 'UTC')    -- the value is independent of the time zone
, ('2014-04-09 23:00+00', 'UTC')    -- only display depends on current time zone
, ('2014-04-09 01:00-07', 'America/Los_Angeles')
, ('2014-04-09 23:00-07', 'America/Los_Angeles');

SELECT start_on, time_zone 
     , start_on::timestamp             AS local_ts
     , start_on AT TIME ZONE time_zone AS ts_at_tz
     , current_date::timestamptz       AS lower_bound
     , (current_date + 1)::timestamptz AS upper_bound
FROM   reservations
WHERE  start_on >= current_date::timestamptz
AND    start_on < (current_date + 1)::timestamptz;

Giải thích thêm và liên kết ở đây:
Bỏ qua hoàn toàn các múi giờ trong Rails và PostgreSQL



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Mới trong PostgreSQL 12:Các cột được tạo

  2. Thêm tên bảng vào mỗi cột trong tập hợp kết quả trong SQL? (Cụ thể là Postgres)

  3. Lỗi:Không thể tạo TypedQuery cho truy vấn có nhiều trả lại

  4. Knex.js buộc sử dụng lại phiên cho 4 truy vấn sau

  5. mã trả về psql nếu không tìm thấy hàng nào