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 / 212195
Accepted
Erwin Brandstetter
Erwin Brandstetter
Asked: 2018-07-14 15:43:29 +0800 CST2018-07-14 15:43:29 +0800 CST 2018-07-14 15:43:29 +0800 CST

Declarar a volatilidade da função IMUTÁVEL pode prejudicar o desempenho?

  • 772

As funções do Postgres são declaradas com classificação de volatilidade VOLATILE, STABLEouIMMUTABLE . O projeto é conhecido por ser muito rigoroso com esses rótulos para funções internas. E com razão. Exemplo proeminente: os índices de expressão permitem apenas IMMUTABLEfunções e essas devem ser verdadeiramente imutáveis ​​para evitar resultados incorretos.

As funções definidas pelo usuário ainda podem ser declaradas conforme a escolha do proprietário. O manual aconselha:

Para obter melhores resultados de otimização, você deve rotular suas funções com a categoria de volatilidade mais estrita que seja válida para elas.

... e adiciona uma extensa lista de coisas que podem dar errado com um rótulo de volatilidade incorreto.

Ainda assim, há casos em que fingir imutabilidade faz sentido. Principalmente quando você sabe que a função é, de fato, imutável dentro do seu escopo. Exemplo:

  • O PostgreSQL suporta agrupamentos “insensíveis ao acento”?

Deixando de lado todas as possíveis implicações na integridade dos dados , qual é o efeito no desempenho? Pode-se supor que declarar uma função IMMUTABLEsó pode ser benéfico para o desempenho . É assim mesmo?

Declarar a volatilidade da função pode IMMUTABLE prejudicar o desempenho?

Vamos assumir o Postgres 10 atual para reduzi-lo, mas todas as versões recentes são interessantes.

postgresql performance
  • 1 1 respostas
  • 2145 Views

1 respostas

  • Voted
  1. Best Answer
    Erwin Brandstetter
    2018-07-14T16:24:47+08:002018-07-14T16:24:47+08:00

    Sim, pode prejudicar o desempenho.

    Funções SQL simples podem ser "embutidas" na consulta de chamada. Citando a Wiki do Postgres :

    As funções SQL (ou seja LANGUAGE SQL, ) terão, sob certas condições, seus corpos de função embutidos na consulta de chamada em vez de serem invocados diretamente. Isso pode ter vantagens substanciais de desempenho, pois o corpo da função fica exposto ao planejador da consulta de chamada, que pode aplicar otimizações como dobra constante, empilhamento de qualidade e assim por diante.

    Minha ênfase em negrito .

    Para impor a correção, há uma série de pré-condições. Um deles :

    se a função for declarada IMMUTABLE, a expressão não deverá invocar nenhuma função ou operador não imutável

    Ou seja, as funções SQL que usam quaisquer funções não imutáveis, mas que ainda estão sendo declaradas IMMTUTABLE, são excluídas dessa otimização. Acionado por essas respostas relacionadas no SO, tenho executado testes extensivos:

    • Como agregar dados de vários anos no MM-DD, ignorando o ano
    • Como você faz matemática de datas que ignora o ano?

    Basicamente comparando essas duas variantes de uma função SQL simples (mapeamento de datas para um integer, ignorando o ano que não importa para o propósito):

    CRIAR FUNÇÃO f_mmdd_tc_s(data)
      RETORNOS int
      IDIOMA sql STABLE     AS
    $$SELECT to_char($1, 'MMDD')::int$$;
    
    CRIAR FUNÇÃO f_mmdd_tc_i(data)
      RETORNOS int
      IDIOMA sql IMUTÁVEL AS
    $$SELECT to_char($1, 'MMDD')::int$$; -- não pode ser embutido!

    A função Postgres to_char()é apenas STABLE, não IMMUTABLE(todas as instâncias sobrecarregadas dela - por motivos além do escopo desta resposta ). Então o segundo é falso IMMUTABLEe acaba sendo 5x mais lento em um teste simples:

    db<>fique aqui

    Este exemplo específico pode ser substituído pelo equivalente:

    CREATE FUNCTION f_mmdd(date)
      RETURNS int
      LANGUAGE sql IMMUTABLE AS
    'SELECT (EXTRACT(month FROM $1) * 100 + EXTRACT(day FROM $1))::int';
    

    Pareceria mais caro com duas chamadas de função e mais cálculos. Mas o IMMUTABLErótulo é verdadeiro (além disso, a função usada é mais rápida e coagir é textmais integercara também).

    2x mais rápido que a variante mais rápida acima (10x mais rápido que a mais lenta). O ponto é: Use IMMUTABLEfunções sempre que possível , então você não precisa "trapacear" para começar.

    • 10

relate perguntas

  • Sequências Biológicas do UniProt no PostgreSQL

  • Como determinar se um Índice é necessário ou necessário

  • Onde posso encontrar o log lento do mysql?

  • Como posso otimizar um mysqldump de um banco de dados grande?

  • 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