PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Kueri Zona Waktu Optimalkan/Indeks

Jika Anda benar-benar memiliki kolom dengan tipe timestamp dan menafsirkannya (sebagian) tergantung pada zona waktu saat ini, dan zona waktu ini dapat bervariasi, maka indeks umumnya tidak mungkin . Anda hanya dapat membuat indeks di IMMUTABLE data ...

Setelah Pembaruan:

Untuk menjawab pertanyaan ini:

  1. Reservasi apa yang dimulai "hari ini"?
  2. Reservasi apa yang memiliki tanggal mulai di masa mendatang?
  3. Reservasi apa yang memiliki tanggal mulai di masa lalu?

... Anda sebaiknya menyimpan timestamp with time zone . Hanya date tidak cukup tepat.

Selama kita hanya tertarik pada "hari ini" lokal (sebagaimana didefinisikan oleh zona waktu saat ini ), kami tidak perlu menyimpan zona waktu secara eksplisit. Kami tidak peduli di dunia mana hal itu terjadi, kami hanya perlu waktu absolut untuk membandingkannya.

Kemudian, untuk mendapatkan reservasi mulai "hari ini" cukup:

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

Tapi ini tidak bisa dicela karena start_on::date adalah ekspresi turunan dan kami juga tidak dapat membangun indeks fungsional untuk ini, (tanpa trik kotor) karena ekspresi bergantung pada zona waktu saat ini dan bukan IMMUTABLE .

Sebaliknya , bandingkan dengan awal dan akhir hari "kami" dalam waktu UTC:

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

Sekarang, indeks sederhana ini dapat mendukung kueri:

CREATE INDEX ON reservations (start_on);

Demo

SQL Fiddle sedang down ATM. Berikut adalah sedikit demo untuk membantu pemahaman:

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;

Penjelasan lebih lanjut dan tautan di sini:
Mengabaikan zona waktu sama sekali di Rails dan 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. Postgis + boost::geometri + C++

  2. Servlet .jar Dependency Null Pointer

  3. Kunci asing + pewarisan tabel di PostgreSQL?

  4. Pencarian teks lengkap Postgresql untuk kata-kata serupa

  5. Menstandardisasi Keamanan PostgreSQL di Lingkungan Multi-Cloud