2009-12-08 11 views
3

J'ai recherché cette question sur Google et je n'arrive pas à trouver une opinion cohérente ou de nombreuses opinions basées sur des données solides. Je voudrais simplement savoir si l'utilisation du caractère générique dans une instruction SQL SELECT implique un surcoût supplémentaire par rapport à l'appel individuel de chaque élément. J'ai comparé les plans d'exécution des deux dans plusieurs requêtes de test différentes, et il semble que les estimations lisent toujours la même chose. Est-il possible que certains frais généraux soient engagés ailleurs ou sont-ils réellement traités de la même façon?Sql générique: surcharge de performance?

Ce que je fais référence à spécifiquement:

SELECT * 

contre

SELECT item1, item2, etc. 
+0

Pouvez-vous clarifier avec un petit exemple? –

+3

Notez également l'utilisation du caractère générique dans le code de production est 99% un symptôme de mauvaise conception. Tu ne devrais pas le faire, jamais. Jamais. Déjà. Je n'ai pas assez de souvenirs mémorisés. –

+0

Je suis d'accord, et je n'utilise jamais le * pour cette raison exacte. Cependant, j'avais lu des opinions vagues que le caractère générique dans une déclaration SELECT entraînerait des frais généraux, et je voulais juste une clarification basée sur des faits, que j'ai eu du mal à trouver. –

Répondre

9
SELECT * FROM... 

et

SELECT every, column, list, ... FROM... 

fait la même chose parce que les deux sont une analyse non optimisé

La différence est:

  • la recherche supplémentaire dans sys.columns pour résoudre *
  • le contrat/signature change lorsque le schéma de la table cha nges
  • incapacité à créer un indice de couverture. En fait, aucune option de réglage du tout, vraiment
  • doivent actualiser les vues nécessaires si non schemabound
  • ne peut pas indexer ou schemabind une vue en utilisant *
  • ... et d'autres choses

Autre SO questions sur le même sujet ...

+0

Pour ajouter, je suppose que le "overhead" dans cette résolution générique est négligeable par rapport au travail réel nécessaire pour extraire les données du disque, etc. –

+0

Vrai, mais les gens le mentionnent souvent. bien sûr, pour 300 colonnes et 10 lignes ..;-) – gbn

+0

Merci pour l'information! –

1

EDIT: Si vous parlez de l'astérisque wild card comme dans Select * From ... puis voir d'autres réponses ...

Si vous parlez de caractères génériques dans les clauses predicate ou d'autres expressions de requête utilisant l'opérateur Like, (_ , %) comme décrit ci-dessous, alors:

Cela a à voir avec si l'utilisation du caractère générique affecte si le SQL est "SARG-ABLE" ou non. SARGABLE, (Search-ARGument-able) signifie si les arguments de recherche ou de tri de la requête peuvent être utilisés comme paramètres d'entrée pour un index existant. Si vous préfixer la carte sauvage au début d'un argument

Where Name Like '%ing' 

Ensuite, il n'y a aucun moyen de traverser un index sur le champ de nom pour trouver les nœuds qui fin en « ing ».

Si Otoh vous ajoutez le caractère générique à la fin,

Where Name like 'Donald%' 

l'optimiseur peut encore utiliser un index sur la colonne de nom, et la requête est toujours SARG-mesure

+0

J'aurais dû être plus précis. J'ai édité pour le faire. Je faisais référence à SELECT * par rapport à une liste SELECT. Cependant, cette réponse me donne un aperçu d'un problème que je n'avais pas pris en compte. Merci! –

2

Voulez-vous dire select * from ... au lieu de select col1, col2, col3 from ...?

Je pense qu'il est toujours préférable de nommer la colonne et récupérer la quantité minimale d'informations, parce que

  • votre code fonctionnera indépendamment de l'ordre physique des colonnes dans la db. L'ordre des colonnes ne devrait pas avoir d'impact sur votre application, mais ce sera le cas si vous utilisez *. Cela peut être dangereux en cas de migration db, etc.
  • Si vous nommez les colonnes, le SGBD peut optimiser davantage l'exécution. Par exemple, s'il existe un index contenant toutes les données qui vous intéressent, la table ne sera pas accessible du tout.

Si vous voulez dire quelque chose d'autre avec "wildcard", ignorez simplement ma réponse ...

+0

C'est le cas dont je parlais, bien que je cherchais à voir où la performance pourrait être encourue autrement que dans le plan d'exécution. Je suis d'accord avec vos raisons de ne pas l'utiliser, cependant. –

0

Si vous appelez voiture sauvage SQL est *. Cela n'implique pas de surcharge de performance par soi-même. Cependant, si la table est étendue, vous pourriez vous retrouver à récupérer des champs que vous ne cherchez pas. En général, ne pas être spécifique dans les champs que vous recherchez ou insérez est une mauvaise habitude. Tenez compte

insert into mytable values(1,2) 

Qu'arrive t-il si la table est étendue à trois champs?

0

Il ne peut pas être plus de travail du point de vue du plan d'exécution. Mais si vous récupérez des colonnes dont vous n'avez pas réellement besoin, c'est une bande passante réseau supplémentaire qui est utilisée entre la base de données et votre application. De même, si vous utilisez une API client de haut niveau qui effectue un certain travail sur les données renvoyées (par exemple, selectall_hashref de Perl), ces colonnes supplémentaires imposeront des coûts de performance du côté client. Combien? Dépend.