Usando Union em vez de OR

Às vezes, consultas lentas podem ser corrigidas modificando ligeiramente a consulta. Um exemplo pode ser ilustrado quando vários valores são comparados em uma cláusula WHERE usando o operador OR ou IN. Geralmente, um OR pode causar uma varredura de índice ou tabela, que pode não ser o plano de execução preferido em termos de consumo de E / S ou velocidade geral da consulta.

Muitas variáveis ​​entram em jogo quando o otimizador de consultas cria um plano de execução. Essas variáveis ​​incluem muitas características de hardware, configurações de instância, configurações de banco de dados, estatísticas (tabela, índice, gerado automaticamente), bem como uma maneira de escrever uma consulta. Aqui, mudamos a maneira como escrevemos a solicitação. Não importa o quão inesperado isso possa parecer, mesmo que duas consultas diferentes possam retornar os mesmos resultados, o caminho a seguir pode ser completamente diferente, dependendo do formato da consulta.

UNION vs OR


Na maior parte da minha experiência com o SQL Server, o OR normalmente é menos eficiente que o UNION. O que geralmente acontece com OU é que muitas vezes causa uma varredura. Às vezes, essa pode ser a melhor maneira para alguns casos, e deixarei como um artigo separado, mas em geral descobri que quando um grande número de entradas é afetado, esse é o principal motivo da lentidão. Então, vamos começar nossa comparação.

Aqui está a nossa declaração OR:

SELECT SalesOrderID, * FROM sales.SalesOrderDetail WHERE ProductID = 750 OR ProductID = 953 



Nesse plano de execução, vemos que estamos verificando 121.000 linhas. (Você não pode ver o número de linhas, mas é).

Agora, executamos a mesma consulta, mas gravada usando UNION em vez de OR:

 SELECT [SalesOrderID], * FROM sales.SalesOrderDetail WHERE ProductID = 750 UNION SELECT [SalesOrderID], * FROM sales.SalesOrderDetail WHERE ProductID = 953 



Aqui vemos dois ramos de operações. Uma ramificação afeta 358 linhas e as outras 346 linhas. As duas ramificações executam uma operação de concatenação que combina os dois conjuntos de resultados. Temos duas pesquisas separadas, mas também temos uma pesquisa chave para obter a lista SELECT necessária. Isso não foi necessário para a operação de verificação, porque ainda afetamos todas as linhas na operação de verificação, portanto os dados foram obtidos durante a verificação, não depois. Isso se deve ao índice e às linhas que precisamos, não a UNION ou OR. No entanto, direi que a seleção também é um fator na escolha de uma pesquisa versus varredura, mas ignoraremos isso neste artigo.

Explicação


Por que o UNION causa mais pesquisas em vez de varreduras, porque cada operação deve atender a um determinado requisito de seletividade para se qualificar para uma pesquisa. (Seletividade é a exclusividade de uma coluna filtrada específica). OU ocorre em uma única operação; portanto, quando a seletividade para cada coluna é combinada e excede uma certa porcentagem, a varredura é considerada mais eficiente.

Como o UNION executa uma operação separada para cada operador por padrão, a seletividade de cada coluna não é combinada, oferecendo uma melhor chance de realizar uma pesquisa. Agora, como o UNION executa duas operações, eles devem corresponder aos seus conjuntos de resultados usando a operação de concatenação descrita acima. Isso geralmente não é uma operação cara.

Também deve ser observado que a cláusula OR funciona da mesma maneira que a instrução IN.

Espero que esta dica ajude. Acredito que isso é muito valioso ao trabalhar com sistemas que exigem alta simultaneidade.

Source: https://habr.com/ru/post/pt464623/


All Articles