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 / 167727
Accepted
user960567
user960567
Asked: 2017-03-22 04:17:01 +0800 CST2017-03-22 04:17:01 +0800 CST 2017-03-22 04:17:01 +0800 CST

Condicionalmente OR vs CASE vs IF

  • 772

Digamos que eu tenha uma pergunta,

SELECT * FROM MyTable WHERE MyParam = 0 OR MyColumn = MyParam

Aqui MyParam é parâmetro e opcional. Então, ele só verifica MyColumn = MyParamse MyParam não é 0. Mas nosso DBA está dizendo que OR fará com que ele fique lento e o db sofrerá. Outra opção é,

IF MyParam = 0 
SELECT * FROM MyTable WHERE MyColumn = MyParam

O problema com essa abordagem é que temos muitos parâmetros opcionais. Então, nossa consulta se tornou muito, muito grande. Outra opção é CASE.

Então o que vocês sugerem. Estou falando em geral se Oracle ou SQL Server.

sql-server oracle
  • 3 3 respostas
  • 5377 Views

3 respostas

  • Voted
  1. Best Answer
    SqlZim
    2017-03-22T04:48:12+08:002017-03-22T04:48:12+08:00

    No sql-server:

    Uma opção é sql dinâmico, outra é option (recompile).

    usando option (recompile):

    select * from MyTable where MyParam = 0 or MyColumn = MyParam option (recompile);
    

    exemplo de sql dinâmico:

    declare @sql nvarchar(max);
    
    if nullif(@MyParam,0) is not null
      begin;
      set @sql = 'select * from MyTable where MyColumn=@MyParam;'
      exec sp_exeuctesql @sql, '@MyParam int', @MyParam;
      end;
    else 
      begin;
      set @sql = 'select * from MyTable;'
      exec sp_exeuctesql @sql;
      end;
    

    Referência:

    • Sniffing, Incorporação e Opções de Recompilação de Parâmetros - Paul White
    • Condições de pesquisa dinâmica - Erland Sommarskog
    • Consultas gerais - Gail Shaw
    • Um exemplo atualizado de "pia de cozinha" - Aaron Bertand
    • 5
  2. Jonathan Fite
    2017-03-22T04:54:33+08:002017-03-22T04:54:33+08:00

    Acabei de executar um teste em meu ambiente no AdventureWorks e descobri que a abordagem CASE funciona melhor. O uso da abordagem OR fez com que o mecanismo usasse o índice clusterizado, onde a instrução CASE permitia que ele usasse o índice não clusterizado.

    para que sua consulta possa ficar assim.

    SELECT *
    FROM MyTable
    WHERE CASE WHEN @MyParam = 0 THEN 1
               WHEN MyColumn = @MyParam THEN 1
               ELSE 0
               END = 1
    

    No entanto, se, como você disse, houver muitos parâmetros, é improvável que você possa usar um índice em qualquer caso. Então você pode deixá-lo sozinho. Meu teste foi para uma consulta simples.

    • 4
  3. AnoE
    2017-03-22T07:23:23+08:002017-03-22T07:23:23+08:00

    SELECT * FROM MyTable WHERE MyParam = 0 OR MyColumn = MyParam

    Mas nosso DBA está dizendo que o OR fará com que seja lento e o db sofrerá.

    Existem várias falhas com isso:

    • O mundo da programação, e especialmente o mundo DB(A) está repleto de ditados como este que se perpetuam ad nauseam. "Nunca use NOT EXISTS, nunca use NOT IN, evite isso, evite aquilo, você deve fazer XYZ a todo custo, evitar ORa todo custo" e assim por diante. O problema com essas coisas é que elas podem ter sido verdadeiras em algum momento, para uma versão específica de um RDBMS específico e, muitas vezes, para um subconjunto específico de configurações de parâmetros para essa versão específica do RDBMS.
    • Isso é em espírito como otimizar antes de saber que há algo para otimizar. A única coisa que é completamente óbvia aqui é que agora você está usando mais tempo nesta declaração (pensando sobre isso, perguntando a SE etc.). Então o custo já subiu. Se a declaração em si é "ruim" nem mesmo foi mostrada, e se realmente é "ruim", alguém nem provou que é ruim o suficiente para justificar uma ação.

    Então, o que você deve fazer nesses casos: criar um caso de teste e fazer um benchmark . Nada mais pode ajudá-lo.

    Para o seu caso específico:

    • O DB poderia , em teoria, otimizar a declaração e reconhecer o problema; poderia então ser quase tão rápido quanto se você tivesse feito de forma diferente.
    • A sobrecarga pode ser insignificante e totalmente inútil para se preocupar. Pode levar 1 ms a mais para uma solicitação que leva 1000 ms de ponta a ponta, com um bom pedaço de código digno de otimização que leva os outros 999 ms. Perder até mesmo um minuto do seu tempo para se preocupar com essas coisas pode ser demais.
    • Por outro lado, esse problema pode ter um tremendo impacto no seu desempenho.

    Faça uma referência; fazer testes; avaliar estatísticas de execução de banco de dados e assim por diante. Então você saberá com certeza.

    • 3

relate perguntas

  • ORDER BY usando prioridades personalizadas para colunas de texto

  • Interface sqlplus confortável? [fechado]

  • Como encontrar as instruções SQL mais recentes no banco de dados?

  • Como posso consultar nomes usando expressões regulares?

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

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