Por que o SSMS está inserindo novas linhas na parte superior de uma tabela e não na parte inferior?

14

Sempre que insiro manualmente uma linha em uma tabela no SQL Server Management Studio 2008 (o banco de dados é SQL Server 2005), minha nova linha aparece na parte superior da lista e não na parte inferior. Estou usando colunas de identidade e isso resulta em coisas como

id  row
42 first row
1 second row
2 third row

Quando as linhas são buscadas e não são ordenadas explicitamente. Isso resulta em uma aparência diferente quando as linhas são buscadas para o aplicativo Web e altera o que uma TOP 1consulta retorna.

Eu sei que posso order by, mas por que isso está acontecendo? A maioria dos meus dados é inserida por meio de um aplicativo da Web. Todas as inserções desse aplicativo resultam em um pedido de primeiro a entrar, por exemplo, a inserção mais recente fica na parte inferior, para que os IDs sejam todos seguidos. Existe alguma configuração no servidor ou no Management Studio que causa esse pedido incorreto?

Ben Brocka
fonte
Como já vi algumas vezes, depende da ordem do PK de como as linhas são exibidas, se você selecionar uma única tabela. Se você fazer algum junta-se, ele pode mudar dependendo dos outros mesas PK, FK das e indexa ...
Guillermo Gutiérrez
Também esteja ciente das varreduras de carrossel .
187 Michael Green

Respostas:

21

No mundo SQL, order não é uma propriedade inerente a um conjunto de dados. Portanto, você não recebe garantias do seu RDBMS de que seus dados retornarão em uma determinada ordem - ou mesmo em uma ordem consistente - a menos que você consulte seus dados com uma ORDER BYcláusula.

De Craig Freedman :

A combinação de TOP com ORDER BY adiciona determinismo ao conjunto de linhas retornadas. Sem ORDER BY, o conjunto de linhas retornadas depende do plano de consulta e pode até variar de execução para execução.

Sempre use ORDER BYse você espera uma ordem bem definida e consistente no seu conjunto de resultados. Nunca confie em como seu banco de dados pode armazenar as linhas no disco (por exemplo, por meio de um índice em cluster) para garantir uma certa ordem de dados em suas consultas.

Nick Chammas
fonte
13

Apenas para aumentar as outras respostas: uma tabela é, por definição, um conjunto não ordenado de linhas. Se você não especificar uma ORDER BYcláusula, o SQL Server poderá retornar as linhas na ordem que julgar mais eficiente. Isso geralmente coincide com a ordem da inserção, já que a maioria das tabelas possui um índice agrupado em identidade, data e hora ou outras colunas que aumentam monotonicamente, mas você deve tratá-lo exatamente assim: uma coincidência. Ele pode ser alterado com novos dados, atualização de estatísticas, sinalizador de rastreamento, alterações no maxdop, dicas de consulta, alterações na cláusula join ou where da consulta, alterações no otimizador devido a um service pack / atualização cumulativa / hotfix / atualização, movendo o banco de dados para um servidor diferente, etc. etc.

Em outras palavras, e eu sei que você já sabe a resposta, mas não pode ser afirmada o suficiente:

Se você deseja confiar na ordem de uma consulta, adicione SEMPRE ORDER BY .

Aaron Bertrand
fonte
Eu não estava pensando em depender do pedido, mas visualmente é um pouco chato que meus últimos itens inseridos estejam subitamente no topo.
Ben Brocka
Suponho que seja porque você está usando a Open Table. No Management Studio 2008, este comando foi divergente em "Editar n linhas superiores" e "Selecionar n linhas superiores" - quando você escolhe a última, você pode editar a consulta resultante, por exemplo, remover a parte superior e adicionar um pedido.
Aaron Bertrand
É o Management studio 2008, o servidor é 2005, deveria ter sido mais claro. Eu não sabia que havia um comando "tabela aberta", eu sempre usei os selectstatments
Ben Brocka
4
Ok, bem, ainda está de pé, entendo que é irritante que os dados retornem em uma ordem que você não espera, mas espero que esteja claro agora por que o SQL Server realmente não se importa com a ordem que você espera, a menos que você diga que se importa adicionando uma ordem por cláusula. :-)
Aaron Bertrand
1

É porque a tabela é uma tabela de heap (provavelmente) e não está indexada. Torne a coluna ID PRIMARY KEYtão boa quanto IDENTITY. O SQL Server armazena fisicamente os dados com base nos índices - por exemplo, se o ID fosse um índice em cluster (como uma chave primária), os dados seriam fisicamente armazenados na ordem dos IDs e seriam retornados dessa maneira em uma consulta mesmo sem uma ORDER BYcláusula. Caso contrário, a ordem das linhas não é importante para o banco de dados. Conseqüentemente, ter um aplicativo depende da ordem das linhas no banco de dados (assim como das colunas estarem em uma determinada ordem) não é uma boa prática. O aplicativo precisa trabalhar com as chaves existentes no banco de dados para identificar linhas.

Wil
fonte
Bom saber. Eu sabia que essa era uma dica para alterar o aplicativo a ser usado order by(é um aplicativo herdado com muita prática incorreta), mas estava pensando exatamente por que isso aconteceu.
Ben Brocka
5
Mude a estrutura da tabela apenas para que, SELECT *semORDER BY possa voltar na ordem "certa" (mas ainda não seja garantida)?
Aaron Bertrand
Em um SELECT simples da tabela com um índice em cluster, ele retornaria na ordem do índice em cluster. Não estava tão claro quanto eu deveria ter sido uma ilustração de quando os dados são ordenados fisicamente por uma coluna específica, mas definitivamente não é certo que em todas as consultas sejam retornados corretamente. Mea culpa.
21711 Wil as
5
Realmente não importa qual é o índice em cluster. O SQL Server ainda pode retornar o pedido com base em algum outro índice com base em uma ampla variedade de fatores. Criar uma chave primária em alguma coluna NÃO garante que as seleções sem ordem retornem subitamente sempre ordenadas por essa coluna. Você pode observar isso na maioria das vezes? Certo. Mas isso não é o mesmo que uma garantia. Eu nunca vi um urso polar na minha rua, mas não há campo de força de urso polar que o impeça de acontecer.
Aaron Bertrand
4
De qualquer forma, meu argumento era que adicionar uma ORDER BYcláusula é uma garantia muito melhor (não importa muito menos perturbadora) do que fazer alterações de esquema na tabela e esperar que a ordem seja a esperada para sempre.
Aaron Bertrand