Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Ordem de linha padrão na consulta SELECT - SQL Server 2008 vs SQL 2012


Você precisa voltar e adicionar ORDER BY cláusulas ao seu código porque sem elas o pedido nunca é garantido. Você teve "sorte" no passado de sempre receber o mesmo pedido, mas não foi porque o SQL Server 2008 o garantia de qualquer maneira. Provavelmente tinha a ver com seus índices ou como os dados estavam sendo armazenados no disco.

Se você mudou para um novo host quando atualizou, a diferença na configuração de hardware por si só pode ter alterado a maneira como suas consultas são executadas. Sem mencionar o fato de que o novo servidor teria recalculado as estatísticas nas tabelas e o otimizador de consulta do SQL Server 2012 provavelmente faz as coisas um pouco diferente do SQL Server 2008.

É uma falácia que você pode confiar na ordem de um conjunto de resultados no SQL sem declarar explicitamente a ordem em que deseja. Resultados do SQL NUNCA tem um pedido no qual você pode confiar sem usar um ORDER BY cláusula. SQL é construído em torno da teoria dos conjuntos. Os resultados da consulta são basicamente conjuntos (ou multiconjuntos).

Itzik Ben-Gan dá uma boa descrição da teoria dos conjuntos em relação ao SQL em seu livro Microsoft SQL Server 2012 T-SQL Fundamentals

A teoria dos conjuntos, que teve origem com o matemático Georg Cantor, é um dos ramos matemáticos em que se baseia o modelo relacional. A definição de Cantor de um conjunto segue:

Por um "conjunto" queremos dizer qualquer coleção M em um conjunto de objetos definidos e distintos m (que são chamados de "elementos" de M) de nossa percepção ou de nosso pensamento. - Joseph W. Dauben e Georg Cantor (Princeton University Press, 1990)

Após uma explicação completa dos termos na definição, Itzik continua dizendo:

O que a definição de conjunto de Cantor deixa de fora é provavelmente tão importante quanto o que ela inclui. Observe que a definição não menciona nenhuma ordem entre os elementos do conjunto. A ordem na qual os elementos do conjunto são listados não é importante. A notação formal para listar elementos do conjunto usa chaves:{a, b, c}. Como a ordem não tem relevância, você pode expressar o mesmo conjunto como {b, a, c} ou {b, c, a}. Avançando para o conjunto de atributos (chamados de colunas em SQL) que compõem o cabeçalho de uma relação (chamado de tabela em SQL), um elemento deve ser identificado pelo nome - não pela posição ordinal. Da mesma forma, considere o conjunto de tuplas (chamadas de linhas pelo SQL) que compõem o corpo da relação; um elemento é identificado por seus valores-chave - não por posição. Muitos programadores têm dificuldade em se adaptar à ideia de que, no que diz respeito à consulta de tabelas, não há ordem entre as linhas. Em outras palavras, uma consulta em uma tabela pode retornar linhas em qualquer ordem a menos que você solicite explicitamente que os dados sejam classificados de uma maneira específica, talvez para fins de apresentação.

Mas independente da definição acadêmica de um conjunto mesmo a implementação em SQL Server nunca garantiu qualquer ordem nos resultados. Esta postagem de blog do MSDN de 2005 por um membro da equipe do otimizador de consulta afirma que você não deve confiar na ordem das operações intermediárias.

As regras de reordenamento podem e irão violar essa suposição (e fazem isso quando for inconveniente para você, o desenvolvedor;). Por favor, entenda que quando reordenamos as operações para encontrar um plano mais eficiente, podemos fazer com que o comportamento de ordenação mude para nós intermediários na árvore. Se você colocou uma operação na árvore que assume uma ordenação intermediária específica, ela pode quebrar.

Esta postagem de blog de Conor Cunningham (Arquiteto, SQL Server Core Engine) "Sem cinto de segurança - Esperando ordem sem ORDER BY" é sobre o SQL Server 2008. Ele tem uma tabela com 20 mil linhas com um único índice que parece sempre retornar linhas em a mesma ordem. Adicionando um ORDER BY à consulta nem altera o plano de execução, portanto, não é como adicionar um que torna a consulta mais cara se o otimizador perceber que não precisa dela. Mas uma vez que ele adiciona outras 20k linhas à tabela, de repente, o plano de consulta muda e agora ele usa paralelismo e os resultados não são mais ordenados!

A parte difícil aqui é que não há uma maneira razoável de qualquer usuário externo saber quando um plano será alterado. O espaço de todos os planos é enorme e dói a cabeça refletir. O otimizador do SQL Server mudará os planos, mesmo para consultas simples, se uma quantidade suficiente de parâmetros for alterada. Você pode ter sorte e não ter uma mudança de plano, ou pode simplesmente não pensar nesse problema e adicionar um ORDER BY.

Se você precisar de mais convencimento, leia estes posts:
  • Sem ORDER BY, não há ordem de classificação padrão. - Alexander Kuznetsov
  • Ordem no tribunal! - Thomas Kyte
  • Ordem de um conjunto de resultados em SQL - Timothy Wiseman