PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Заявка за оптимизиране/индексиране на часова зона

Ако действително имате колона от тип timestamp и го интерпретира (на части) в зависимост от текущата часова зона и тази часова зона може да варира, тогава индексът обикновено е невъзможен . Можете да създадете индекс само върху IMMUTABLE данни ...

След актуализация:

За да отговорите на тези въпроси:

  1. Какви резервации започват „днес“?
  2. Кои резервации имат начални дати в бъдеще?
  3. Кои резервации имат начални дати в миналото?

... най-добре съхранявайте timestamp with time zone . Само date не е достатъчно точен.

Докато се интересуваме само от местното „днес“ (както е определено от текущата часова зона ), ние го правимне трябва изрично да запазите часовата зона. Не ни интересува къде по света ще се случи, имаме нужда само от абсолютно време за сравнение.

След това, за да получите резервации, започващи „днес“, просто:

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

Но това не може да се копира защото start_on::date е производен израз и не можем да изградим функционален индекс и за него (без мръсни трикове), защото изразът зависи от текущата часова зона и не е IMMUTABLE .

Вместо това , сравнете с началото и края на "нашия" ден в UTC време:

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

Сега този прост индекс може да поддържа заявката:

CREATE INDEX ON reservations (start_on);

Демо

SQL Fiddle не работи ATM. Ето малка демонстрация за разбиране:

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;

Повече обяснения и връзки тук:
Пълно игнориране на часовите зони в Rails и 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. PHP json_encode Проблем с обратна наклонена черта и име на масив

  2. Как да проверите дали lat long е в границите на града

  3. Изключете дефиниции на функции при изхвърляне на PostgreSQL база данни

  4. Динамично дефиниране на връщащи типове редове въз основа на предадена дадена таблица в plpgsql?

  5. @@Fetch_status в postgreSQL