AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 195202
Accepted
John Bachir
John Bachir
Asked: 2018-01-12 11:00:47 +0800 CST2018-01-12 11:00:47 +0800 CST 2018-01-12 11:00:47 +0800 CST

Qual é a melhor maneira de usar um índice gist em tsrange para verificar se ocorre um horário após o intervalo?

  • 772

tabela (simplificada)

                                        Table "public.events"
      Column      |            Type             |                       Modifiers                        
------------------+-----------------------------+--------------------------------------------------------
 id               | integer                     | not null default nextval('events_id_seq'::regclass)
 duration         | integer                     | not null
 start_at         | timestamp without time zone | 
Indexes:
    "events_pkey" PRIMARY KEY, btree (id)
    "my_idx" gist (tsrange(start_at, end_at(events.*), '[)'::text))

função

CREATE FUNCTION end_at(rec events)
  RETURNS timestamp without time zone
  IMMUTABLE
  LANGUAGE SQL
AS $$
  SELECT $1.start_at + ($1.duration * ('00:00:01'::interval));
$$;

o que já estou fazendo com sucesso

O índice é usado para consultas como esta:

-- check if current time is within the start and end times
-- of event
where localtimestamp <@ tsrange(start_at, events.end_at, '[)')

E funciona bem.

O que eu quero fazer

Quero consultar eventos em que a hora atual é depois que eles terminaram. Maneiras que eu conheço de como fazer isso:

  • where tsrange(localtimestamp, localtimestamp, '[]') >> tsrange(start_at, events.end_at, '[)'). Tenho certeza de que essa é a semântica que quero e explain analyzediz que está usando o índice, mas é um pouco feio e estou imaginando se há uma maneira melhor de expressar isso (e também estou vagamente incerto é a semântica que quero, pois Eu sou novo em intervalos).
  • where localtimestamp > upper(tsrange(start_at, events.end_at, '[)'))+ um índice btree em upper(tsrange(start_at, events.end_at, '[)')). Isso funcionará bem, mas requer manter outro índice por perto.
  • where localtimestamp > events.end_at. + um índice btree em events.end_at. Mesma situação acima.

Existe uma maneira mais elegante (ou correta) de alcançar o primeiro ponto acima?

Alguma outra ideia de como fazer isso?

postgresql index
  • 2 2 respostas
  • 1482 Views

2 respostas

  • Voted
  1. Best Answer
    John Bachir
    2018-04-14T09:01:57+08:002018-04-14T09:01:57+08:00

    O Postgres não suporta nenhum operador para isso. Como apontado por @evan-carroll, provavelmente poderia e deveria.

    Então, a melhor solução é

    where tsrange(localtimestamp, localtimestamp, '[]') >> tsrange(start_at, events.end_at, '[)')
    
    • 1
  2. Evan Carroll
    2018-01-12T13:02:57+08:002018-01-12T13:02:57+08:00

    Quero consultar eventos em que a hora atual é depois que eles terminaram. Maneiras que eu conheço de como fazer isso:

    Você pode ver os operadores GiST aqui . Você pode ver a lista em range_ops,

    && &> &< >> << <@ -|- = @> @>
    

    Como você indicou, o que você provavelmente quer é <<, >>. eu usaria <<.

    É feio? Sim. O tipo de range é ótimo se você estiver trabalhando com ranges em ambos os lados, aqui você não está. Você nem está armazenando o tipo de intervalo na mesa. Eu recomendaria que você fizesse isso.

    Não tenho certeza se essa condição de índice funciona,

    "my_idx" gist (tsrange(start_at, end_at(events.*), '[)'::text))
    

    Você testou isso? Quero dizer, o PostgreSQL pode verificar o start_atfuncionamento, minha suposição é que não é inteligente o suficiente para trabalhar com end_at( events.*e se um dos valores (colunas) usados ​​no end_atarquivo for alterado da criação da tabela para a chamada? Mesmo que nunca aconteça, como o PostgreSQL saiba disso). Eu armazenaria o tsrangena tabela e descartaria todas as colunas associadas.

    Ignore o abaixo, olhando para ele.

    Além disso, você pode considerar torná-lo mais curto não construindo o intervalo rhs.

    SELECT tsrange('yesterday', 'tomorrow') @> timestamp without time zone 'now';
    SELECT tsrange('yesterday', 'tomorrow') @> 'now'::timestamp without time zone;
    

    Ou algo parecido, se você preferir esse formato. Ou o seguinte, que parece um antipadrão.

    SELECT tsrange('yesterday', 'tomorrow') @> '[now,now]';
    

    Ou você pode usar tstzrange(o que provavelmente é uma ideia melhor),

    SELECT tstzrange('yesterday', 'tomorrow') @> now();
    

    • 0

relate perguntas

  • Quanto "Padding" coloco em meus índices?

  • Sequências Biológicas do UniProt no PostgreSQL

  • O que significa "índice" em RDBMSs? [fechado]

  • Como criar um índice condicional no MySQL?

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve