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 / 105525
Accepted
Erik Bergstedt
Erik Bergstedt
Asked: 2015-07-01 03:16:42 +0800 CST2015-07-01 03:16:42 +0800 CST 2015-07-01 03:16:42 +0800 CST

Desempenho do índice em ON versus WHERE

  • 772

Eu tenho duas mesas

@T1 TABLE
(
    Id INT,
    Date DATETIME
)

@T2 TABLE
(
    Id INT,
    Date DATETIME
)

Essas tabelas têm um índice não clusterizado em (Id, Data)

E eu junto essas mesas

SELECT *
FROM T1 AS t1
INNER JOIN T2 AS t2
ON 
    t1.Id = t2.Id
WHERE 
    t1.Date <= GETDATE()
    AND
    t2.Date <= GETDATE()

Isso também pode ser escrito como

SELECT *
FROM T1 AS t1
INNER JOIN T2 AS t2
ON 
    t1.Id = t2.Id
    AND
    t1.Date <= GETDATE()
    AND
    t2.Date <= GETDATE()

Minha pergunta é: qual dessas duas consultas oferece o melhor desempenho e por quê? Ou são iguais?

sql-server index
  • 6 6 respostas
  • 3179 Views

6 respostas

  • Voted
  1. Best Answer
    Tom V
    2015-07-01T03:26:48+08:002015-07-01T03:26:48+08:00

    O desempenho será o mesmo. O otimizador reconhecerá isso e criará o mesmo plano.

    Por outro lado, eu não diria que são iguais. A primeira forma da pergunta é muito mais legível e geralmente esperada.

    Para um exemplo usando algumas tabelas que tenho em mãos, você pode ver que o plano de execução é exatamente o mesmo, não importa como eu escreva a consulta.

    Você deve ser capaz de determinar os planos de consulta para suas próprias tabelas e conjuntos de dados para poder ver o que acontece em sua situação.

    SELECT * FROM salestable , custtable 
    WHERE salestable.custaccount = custtable.accountnum 
    AND salestable.dataareaid = custtable.dataareaid
    
    SELECT * FROM salestable 
    JOIN  custtable 
    ON salestable.custaccount = custtable.accountnum 
    AND salestable.dataareaid = custtable.dataareaid
    
    SELECT * FROM salestable JOIN custtable 
    ON salestable.custaccount = custtable.accountnum 
    WHERE salestable.dataareaid = custtable.dataareaid
    

    Dá esses planos de execução

    insira a descrição da imagem aqui

    • 32
  2. Martin Smith
    2015-07-01T03:21:49+08:002015-07-01T03:21:49+08:00

    Eles são semanticamente idênticos e o otimizador não deve ter problemas para reconhecer esse fato e gerar planos idênticos.

    Costumo colocar condições referenciando ambas as tabelas no ONe condições referenciando apenas uma tabela no WHERE.

    No OUTER JOINSentanto, para mover, as condições podem afetar a semântica.

    • 22
  3. Jared Karney
    2015-08-04T05:30:16+08:002015-08-04T05:30:16+08:00

    Em casos simples, será o mesmo. No entanto, tenho visto consultas muito complexas com várias junções com planos significativamente diferentes. Um recente em que eu estava trabalhando começou com uma tabela que tem cerca de 6 milhões de linhas unidas a cerca de 20 tabelas diferentes. Somente a primeira junção a esta tabela foi uma junção interna , todas as outras foram deixadas como junções externas. O filtro na cláusula where foi parametrizado mais ou menos assim:

    WHERE table1.begindate >= @startdate AND table1.enddate < @enddate 
    

    Esse filtro foi usado posteriormente no plano em vez de anteriormente. Quando movi essas condições para a primeira junção interna, o plano mudou drasticamente, pois o filtro foi aplicado no início do plano para limitar o conjunto de resultados e minha CPU e o tempo decorrido caíram aproximadamente 310%. Então, como acontece com muitas questões do SQL Server, depende.

    • 7
  4. Tom Evers
    2015-08-04T11:39:51+08:002015-08-04T11:39:51+08:00

    Em geral, onde você coloca os filtros faz diferença.
    Embora Tom V diga que o Optimizer reconhecerá que as consultas são as mesmas e apresentará o mesmo plano, isso nem sempre é verdade. Depende de qual versão do SQL você está, quão complexa é sua consulta e quão importante para o lote geral o Otimizador determina que a consulta é.

    O Otimizador pode decidir que esta parte do lote não vale a pena gastar tempo suficiente para permitir que ele apresente o melhor plano. Em geral, você obterá um melhor desempenho se colocar condições que reduzam a quantidade de dados que a consulta precisará para trabalhar na cláusula ON em vez da cláusula WHERE (se possível, pois fazer isso com uma junção externa resultará em um produto cartesiano . )

    É um pouco mais fácil para o desenvolvedor SQL ocasional localizar filtros na cláusula WHERE, mas trabalhei em algumas tabelas grandes onde ter os filtros na cláusula ON economiza horas no tempo de execução.

    Portanto, se a cláusula tiver o potencial de reduzir drasticamente o número de linhas que a consulta lerá, sempre a colocarei na cláusula ON para ajudar o Otimizador a escolher o melhor plano.

    • 2
  5. McB2K3
    2015-08-23T08:00:56+08:002015-08-23T08:00:56+08:00

    Em circunstâncias comuns, as condições do filtro podem ser especificadas nas cláusulas WHERE ou JOIN. Costumo colocar filtros em WHERE, a menos que a precedência OUTER JOIN possa ser afetada (veja abaixo) ou se o filtro for muito específico para essa tabela (por exemplo, TYPE=12 para especificar um subconjunto específico de linhas na tabela).

    Por outro lado, as cláusulas ON e WHERE podem ser usadas para especificar as condições de junção (em oposição às condições de filtro). Contanto que você esteja usando apenas junções INNER, ainda não importa qual você usa em circunstâncias normais.

    Se você estiver usando junções OUTER, no entanto, isso pode fazer uma grande diferença. Se, por exemplo, você especificar um OUTER JOIN entre duas tabelas (t1 e t2), mas depois, na cláusula WHERE, especificar um relacionamento eqijoin entre as tabelas (por exemplo, t1.col = t2.col), você acabou de converteu a junção OUTER em uma junção INNER! Isso ocorre porque WHERE pode ser usado para especificar um equijoin (ou talvez até OUTER join, dependendo da versão, usando a obsoleta sintaxe *=) sem usar uma cláusula ON, e quando WHERE indica um equijoin interno entre tabelas, ele substitui um OUTER JOIN (se presente).

    A pergunta original era sobre filtros, onde o tipo de junção geralmente não deveria ser um problema, mas uma junção também pode atuar como um filtro e, nessas situações, o posicionamento da condição de junção certamente pode ser importante.

    • 1
  6. Sean Redmond
    2015-08-04T00:30:47+08:002015-08-04T00:30:47+08:00

    Com INNER JOINs, é uma questão de estilo.

    No entanto, torna-se muito mais interessante com OUTER JOINs. Você deve explorar as diferenças entre consultas com OUTER JOINs e condições nas cláusulas ON e WHERE. O conjunto de resultados nem sempre é o mesmo. É, por exemplo,

    OUTER JOIN dbo.x ON a.ID = x.ID ... WHERE x.SomeField IS NOT NULL
    

    o mesmo que

    INNER JOIN dbo.x ON a.ID = x.ID AND x.SomeField IS NOT NULL
    
    • -1

relate perguntas

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Quanto "Padding" coloco em meus índices?

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

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

  • Como criar um índice condicional no MySQL?

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