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 / user-2179

Zilk's questions

Martin Hope
Zilk
Asked: 2017-10-10 08:27:36 +0800 CST

O PostgreSQL reescreve JOINs com ORs em UNIONs?

  • 2

(Abreviado) resumo da tabela:

-- Table cases:
     id                  SERIAL       PRIMARY KEY,
     application_number  VARCHAR(30)  NOT NULL,
     publication_number  VARCHAR(30)  NOT NULL,

-- Table patents:
     case_id                 INTEGER      PRIMARY KEY,  -- FK to cases(id)
     pct_application_number  VARCHAR(30)  NOT NULL,
     pct_publication_number  VARCHAR(30)  NOT NULL,

-- All character columns have working trigram indexes:
     CREATE INDEX cases_application_number_trgm_idx ON cases
         USING GIN (application_number gin_trgm_ops);
         -- (etc)

A consulta a seguir é lenta (~200ms) porque não usa os índices:

SELECT  c.id
  FROM  cases c
        JOIN patents p ON p.case_id = c.id
 WHERE  c.application_number ILIKE '%1234%' OR p.pct_application_number ILIKE '%1234%'

As seguintes consultas são todas rápidas (1-2ms):

-- AND instead of OR
WHERE  c.application_number ILIKE '%1234%' AND p.pct_application_number ILIKE '%1234%'

-- OR, but only table "cases"
WHERE  c.application_number ILIKE '%1234%' OR c.publication_number ILIKE '%1234%'

-- OR, but only table "patents"
WHERE  p.pct_application_number ILIKE '%1234%' OR p.pct_publication_number ILIKE '%1234%'

-- Simulating the OR with a UNION
SELECT  c.id
  FROM  cases c
        JOIN patents p ON p.case_id = c.id
 WHERE  c.application_number ILIKE '%1234%'
 UNION
SELECT  c.id
  FROM  cases c
        JOIN patents p ON p.case_id = c.id
 WHERE  p.pct_application_number ILIKE '%1234%'

Aqui está a EXPLAIN ANALYZEsaída para a consulta lenta:

                                                         QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------
 Hash Join  (cost=2329.80..10590.54 rows=7 width=4) (actual time=54.951..186.713 rows=35 loops=1)
   Hash Cond: (c.id = p.case_id)
   Join Filter: (((c.application_number)::text ~~* '%1234%'::text) OR ((p.pct_application_number)::text ~~* '%1234%'::text))
   Rows Removed by Join Filter: 68223
   ->  Seq Scan on cases c  (cost=0.00..4981.99 rows=142099 width=12) (actual time=0.011..32.875 rows=142099 loops=1)
   ->  Hash  (cost=1142.58..1142.58 rows=68258 width=11) (actual time=31.105..31.105 rows=68258 loops=1)
         Buckets: 131072  Batches: 2  Memory Usage: 2473kB
         ->  Seq Scan on patents p  (cost=0.00..1142.58 rows=68258 width=11) (actual time=0.019..11.995 rows=68258 loops=1)
 Planning time: 1.875 ms
 Execution time: 186.780 ms
(10 rows)

A consulta como postada aqui é bastante reduzida para ilustrar o problema. A consulta real é mais complexa e envolve uma pesquisa de texto em seis (ou mais) colunas em cinco (ou mais) tabelas, com cerca de 10 colunas de saída. Acho que eu poderia reescrever tudo isso como uma série de consultas e conectá-las em um enorme UNION... existe uma maneira melhor de lidar com esse problema?


Adicionando plano de consulta com enable_seqscandesabilitado (conforme solicitado):

                                                                QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------
 Merge Join  (cost=0.71..18767.92 rows=7 width=4) (actual time=4.809..150.368 rows=35 loops=1)
   Merge Cond: (c.id = p.case_id)
   Join Filter: (((c.application_number)::text ~~* '%1234%'::text) OR ((p.pct_application_number)::text ~~* '%1234%'::text))
   Rows Removed by Join Filter: 68223
   ->  Index Scan using cases_pkey on cases c  (cost=0.42..14942.96 rows=142099 width=12) (actual time=0.004..32.695 rows=142097 loops=1)
   ->  Index Scan using patents_pkey on patents p  (cost=0.29..2275.63 rows=68258 width=11) (actual time=0.003..11.942 rows=68258 loops=1)
 Planning time: 1.007 ms
 Execution time: 150.399 ms
(8 rows)
postgresql index
  • 1 respostas
  • 229 Views
Martin Hope
Zilk
Asked: 2016-12-13 10:54:10 +0800 CST

Por que o PostgreSQL não usa um índice quando OR é usado nas condições?

  • 3

Estrutura do banco de dados resumida:

  • a tabela principal é cases(cerca de 136k linhas)
  • cada caso pode ter 0 - n linhas de referência na tabelacase_contacts
  • cada contato de caso faz referência a um contato principal na tabelacontacts
  • um contato de caso também pode fazer referência a um subcontato secundário, também na tabelacontacts
  • os contatos têm seus nomes em contacts.v_fullname, que é indexado com um índice trigrama

O objetivo é encontrar casos em que o nome de um contato ou subcontato contenha a string "teste":

SELECT  c.id,
        c.number
  FROM  cases c
        JOIN case_contacts caco ON caco.case_id = c.id
        JOIN contacts con_main ON con_main.id = caco.contact_id
        LEFT JOIN contacts con_sub ON con_sub.id = caco.subcontact_id
 WHERE  con_main.v_fullname ILIKE '%test%'
        OR con_sub.v_fullname ILIKE '%test%'

Esta consulta ( plano de consulta ) retorna o resultado correto, mas não utiliza o índice do trigrama. Demora cerca de 330ms.

Remover qualquer uma das condições de correspondência ( plano de consulta ) ou fazer com que apontem para a mesma tabela ( plano de consulta ) remove o problema de desempenho. Ambos usam o índice do trigrama e são executados em menos de 1ms, mas não resolvem a tarefa dada.

Como posso fazer com que o PostgreSQL use meu índice?

Simplifiquei este exemplo ao mínimo necessário para demonstrar o efeito. A consulta real é muito mais complexa (e parcialmente gerada automaticamente), portanto, usar uma UNION de duas consultas com apenas uma correspondência de texto cada seria muito difícil, se é que é possível.

Estou usando o PostgreSQL 9.5.5.
O esquema ainda está aberto para modificações (até certo ponto).


Conforme solicitado, mais informações sobre os índices:

dbname=# \di+ *contacts*
                                         List of relations
 Schema |               Name               | Type  | Owner |     Table     |  Size
--------+----------------------------------+-------+-------+---------------+---------
 public | case_contacts_case_id_idx        | index | x     | case_contacts | 4544 kB
 public | case_contacts_contact_id_idx     | index | x     | case_contacts | 4544 kB
 public | case_contacts_id_case_id_idx     | index | x     | case_contacts | 4544 kB
 public | case_contacts_idx                | index | x     | case_contacts | 9608 kB
 public | case_contacts_pkey               | index | x     | case_contacts | 4544 kB
 public | case_contacts_reference_trgm_idx | index | x     | case_contacts | 4960 kB
 public | case_contacts_subcontact_id_idx  | index | x     | case_contacts | 4544 kB
 public | case_contacts_type_idx           | index | x     | case_contacts | 6208 kB
 public | case_contacts_unique_types_idx   | index | x     | case_contacts | 5464 kB
 public | contacts_parent_id_id_idx        | index | x     | contacts      | 456 kB
 public | contacts_parent_id_idx           | index | x     | contacts      | 360 kB
 public | contacts_pkey                    | index | x     | contacts      | 360 kB
 public | contacts_v_fullname_trgm_idx     | index | x     | contacts      | 1560 kB
(13 rows)

É assim que o índice em contacts.v_fullname é criado:

CREATE INDEX contacts_v_fullname_trgm_idx ON contacts USING GIN (v_fullname gin_trgm_ops);
postgresql index
  • 1 respostas
  • 1469 Views
Martin Hope
Zilk
Asked: 2016-10-27 07:57:17 +0800 CST

Por que as chaves estrangeiras compostas precisam de uma restrição exclusiva separada?

  • 14

Aqui está uma tabela simples onde os registros podem fazer referência a registros pai na mesma tabela:

CREATE TABLE foo (
    id         SERIAL  PRIMARY KEY,
    parent_id  INT     NULL,
    num        INT     NOT NULL,
    txt        TEXT    NULL,
    FOREIGN KEY (parent_id) REFERENCES foo(id)
);

Com o requisito adicionado de que um dos outros valores de campo ( num) deve ser idêntico entre os registros pai e filho, pensei que uma chave estrangeira composta deveria funcionar. Eu mudei a última linha para

    FOREIGN KEY (parent_id, num) REFERENCES foo(id, num)

e obtive ERRO: não há nenhuma restrição exclusiva correspondente às chaves fornecidas para a tabela referenciada "foo" .

Posso facilmente adicionar essa restrição, mas não entendo por que é necessário, quando uma das colunas referenciadas ( id) já é garantida como única? A meu ver, a nova restrição seria redundante.

postgresql foreign-key
  • 2 respostas
  • 15872 Views
Martin Hope
Zilk
Asked: 2015-12-19 09:18:01 +0800 CST

Restaurar banco de dados PostgreSQL (ou nomes de banco de dados) para uma nova versão, a partir de arquivos?

  • 3

Cenário resumido:

  • um laptop de desenvolvimento quebrou
  • HDD antigo ainda é legível
  • novo laptop tem PostgreSQL 9.4 em vez de 9.1
  • ambos os laptops usam um sabor do Ubuntu Linux

Pergunta 1: Meu entendimento está correto de que, para restaurar os dados antigos, eu precisaria de um servidor com a mesma versão principal+secundária daquele que gravou o diretório de dados antigo? Como nenhum pacote 9.1 está disponível para minha distribuição, eu teria que compilar um servidor v9.1.x a partir do código-fonte, copiar os dados antigos, iniciar o servidor e executar um pg_dump normal, que poderia então ser restaurado para o novo cluster?

Pergunta 2: Havia cerca de 10 a 15 bancos de dados no laptop antigo, mas como era uma máquina de desenvolvimento, em teoria todos os dados deveriam ser substituíveis, exceto alguns experimentos locais. Estou pensando em apenas descartar os dados antigos, mas não consigo me lembrar com 100% de certeza quais eram esses bancos de dados. Existe uma maneira de extrair algumas informações básicas (como nomes de banco de dados, talvez até tamanhos ou registros de data e hora) do diretório de dados antigo sem executar um servidor 9.1?

postgresql linux
  • 2 respostas
  • 159 Views
Martin Hope
Zilk
Asked: 2011-06-21 14:53:22 +0800 CST

É possível criar/restaurar rapidamente instantâneos de banco de dados com o PostgreSQL?

  • 60

Em primeiro lugar, sou um desenvolvedor, não um DBA ou administrador de sistemas; por favor, seja gentil :)

Estou trabalhando em um fluxo de trabalho de aplicativo em que uma única ação do usuário acionará alterações complexas no banco de dados - criando centenas de registros em algumas tabelas, atualizando centenas de registros em outras, etc. Ao todo, cerca de 12 tabelas (de ~ 100 ) são tocados por esta ação. Devido à complexidade, é muito difícil para mim reverter manualmente todas as alterações antes de poder executar outro teste. Durante a maior parte do meu tempo de desenvolvimento, posso simplesmente inserir uma instrução "ROLLBACK" perto do final do fluxo de trabalho, mas quando chego perto de confirmar minhas alterações, preciso testar a coisa real.

Eu tenho uma cópia local do banco de dados de produção para trabalhar. No meu caso, despejar e restaurar entre os testes é mais rápido do que escrever um script para desfazer todas as alterações. É mais rápido, mas ainda está me deixando muito lento (a restauração leva cerca de 20 minutos no meu laptop antigo). Existe alguma maneira de salvar um instantâneo do estado atual do banco de dados e restaurá-lo rapidamente?

Tenho a garantia de ser o único usuário no sistema e tenho acesso root. O dump do banco de dados é ~ 100 MB quando tar'ed e gzip'ed. A versão do PostgreSQL é 8.3.

Agradecemos antecipadamente por quaisquer idéias úteis.

postgresql restore
  • 8 respostas
  • 35608 Views

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