85 votes

Pourquoi utiliser Select Top 100 Percent ?

Je comprends qu'avant de SQL Server 2005 Si l'on veut que le serveur SQL permette l'utilisation d'une commande par dans une définition de vue, il faut inclure l'élément suivant TOP 100 PERCENT dans le SÉLECTIONNER clause. Mais j'ai vu d'autres codes dont j'ai hérité qui utilisent SELECT TOP 100 PERCENT ... au sein des instructions SQL dynamiques (utilisées dans les applications ADO sur ASP.NET applications, etc). Y a-t-il une raison à cela ? Le résultat n'est-il pas le même que no y compris le TOP 100 PERCENT ?

5 votes

Peut-être qu'il y a une déclaration de construction en cours : "SÉLECTIONNER LE TOP {0} POUR CENT..."

0 votes

Votre première phrase est devenue la réponse à une de mes questions cachées.

0 votes

J'utilise les 99,9999999 POURCENT les plus élevés et ça marche toujours. C'est assez proche. J'ai tendance à ajouter le nombre de '9' en fonction du nombre d'enregistrements prévus. Plus d'enregistrements, plus de '9' et ça marche toujours. Je l'ai utilisé de SQL 2008 à SQL 2017.

53voto

gbn Points 197263

Il a été utilisé pour " matérialisation intermédiaire (recherche Google) "

Bon article : Adam Machanic : Explorer les secrets de la matérialisation intermédiaire

Il a même soulevé un MS Connect pour qu'il puisse être fait de manière plus propre

Mon avis est "pas intrinsèquement mauvais", mais ne l'utilisez pas à moins d'être sûr à 100%. Le problème est que cela ne fonctionne qu'au moment où vous le faites et probablement pas plus tard (niveau de patch, schéma, index, nombre de lignes, etc)...

Exemple concret

Cela peut échouer parce que vous ne savez pas dans quel ordre les choses sont évaluées.

SELECT foo From MyTable WHERE ISNUMERIC (foo) = 1 AND CAST(foo AS int) > 100

Et cela peut aussi échouer parce que

SELECT foo
FROM
    (SELECT foo From MyTable WHERE ISNUMERIC (foo) = 1) bar
WHERE
    CAST(foo AS int) > 100

Cependant, ce n'était pas le cas dans SQL Server 2000. La requête interne est évaluée et spooled :

SELECT foo
FROM
    (SELECT TOP 100 PERCENT foo From MyTable WHERE ISNUMERIC (foo) = 1 ORDER BY foo) bar
WHERE
    CAST(foo AS int) > 100

Remarque : cela fonctionne toujours dans SQL Server 2005

SELECT TOP 2000000000 ... ORDER BY...

0 votes

Pourquoi la deuxième requête échoue-t-elle ? Parce que la requête interne n'est pas (nécessairement) entièrement évaluée ?

0 votes

Ce deuxième lien explique pourquoi la création de tables temporaires permet parfois d'améliorer considérablement les performances !

43voto

Steve Kass Points 4738

Le pourcentage TOP (100) n'a aucune signification dans les versions récentes de SQL Server, et il est ignoré par le processeur de requêtes (tout comme le ORDER BY correspondant, dans le cas d'une définition de vue ou d'une table dérivée).

Vous avez raison de dire qu'il fut un temps où l'on pouvait l'utiliser comme une astuce, mais même là, ce n'était pas fiable. Malheureusement, certains des outils graphiques de Microsoft ont intégré cette clause dénuée de sens.

Quant à savoir pourquoi cela peut apparaître dans le SQL dynamique, je n'en ai aucune idée. Vous avez raison de dire qu'il n'y a aucune raison à cela et que le résultat est le même sans cela (et encore, dans le cas d'une définition de vue ou d'une table dérivée, sans les clauses TOP et ORDER BY).

0 votes

Ce n'est pas vrai ; voir ceci lien de la réponse de @gbn pour plus de détails.

5 votes

Le lien que vous mentionnez ne parle pas de SELECT TOP (100) PERCENT .. ORDER BY, ce qui n'a aucun sens. Le lien mentionne l'utilisation de SELECT TOP (2147483647) .. ORDER BY. Actuellement, l'optimiseur de SQL Server élimine SELECT TOP (100) PERCENT .. ORDER BY, parce que cela n'a aucun sens. Cette combinaison définit toujours la même collection de lignes que SELECT sans TOP/ORDER BY. Actuellement, l'optimiseur ne tente pas de déterminer si 2147483647 comprend toutes les lignes, il n'élimine donc pas la combinaison TOP - ORDER BY dans ce cas.

2 votes

Le lien mentionne effectivement TOP (100) PERCENT : "... Je pourrais essayer de forcer la matérialisation intermédiaire de la table dérivée, sans la table temporaire, en utilisant TOP 100 PERCENT conjointement avec ORDER BY. Malheureusement, l'équipe de l'optimiseur de requêtes de SQL Server a décidé que ce n'était pas une bonne idée, et l'optimiseur ignore désormais de telles tentatives." En fait, il vous soutient.

24voto

OMG Ponies Points 144785

...permettre l'utilisation d'un ORDER BY dans une définition de vue.

Ce n'est pas une bonne idée. Une vue ne devrait jamais avoir un ORDER BY défini.

Un ORDER BY a un impact sur les performances - son utilisation dans une vue signifie que l'ORDER BY apparaîtra dans le plan d'explication. Si vous avez une requête où la vue est jointe à n'importe quel élément de la requête immédiate, ou référencée dans une vue en ligne (factorisation CTE/sous-requête), le ORDER BY est toujours exécuté avant le ORDER BY final (en supposant qu'il ait été défini). Il n'y a aucun avantage à ordonner les lignes qui ne sont pas le jeu de résultats final lorsque la requête n'utilise pas TOP (ou LIMIT pour MySQL/Postgres).

Pensez-y :

CREATE VIEW my_view AS
    SELECT i.item_id,
           i.item_description,
           it.item_type_description
      FROM ITEMS i
      JOIN ITEM_TYPES it ON it.item_type_id = i.item_type_id
  ORDER BY i.item_description

...

  SELECT t.item_id,
         t.item_description,
         t.item_type_description
    FROM my_view t
ORDER BY t.item_type_description

...est l'équivalent d'utiliser :

  SELECT t.item_id,
         t.item_description,
         t.item_type_description
    FROM (SELECT i.item_id,
                 i.item_description,
                 it.item_type_description
            FROM ITEMS i
            JOIN ITEM_TYPES it ON it.item_type_id = i.item_type_id
        ORDER BY i.item_description) t
ORDER BY t.item_type_description

C'est mauvais parce que :

  1. Dans cet exemple, la liste est d'abord classée en fonction de la description de l'article, puis elle est réorganisée en fonction de la description du type d'article. Il s'agit d'un gaspillage de ressources dans le premier tri - le fonctionnement en l'état fait que no signifie que c'est en cours : ORDER BY item_type_description, item_description
  2. Il n'est pas évident de savoir par quoi la vue est ordonnée en raison de l'encapsulation. Cela ne signifie pas que vous devez créer plusieurs vues avec des ordres de tri différents...

6voto

Mitch Wheat Points 169614

S'il n'y a pas de ORDER BY alors TOP 100 PERCENT est redondant. (Comme vous le mentionnez, c'était le "truc" avec les vues).

(Avec un peu de chance, l'optimiseur optimisera cela).

5voto

Joel Coehoorn Points 190579

J'ai vu d'autres codes dont j'ai hérité et qui utilisent SELECT TOP 100 PERCENT.

La raison en est simple : Enterprise Manager essayait d'être utile et de formater votre code afin d'inclure ces éléments pour vous. Il était inutile d'essayer de le supprimer, car cela ne faisait pas de mal et la prochaine fois que vous vouliez le modifier, EM le réinsérait.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X