web-dev-qa-db-fra.com

Lequel est le plus rapide / meilleur? SELECT * ou SELECT colonne1, colonne2, colonne3, etc.

J'ai entendu dire que SELECT * est généralement une mauvaise pratique à utiliser lors de l’écriture de commandes SQL car il est plus efficace de SELECT colonnes dont vous avez spécifiquement besoin.

Si j’ai besoin de SELECT chaque colonne d’un tableau, dois-je utiliser

SELECT * FROM TABLE

ou

SELECT column1, colum2, column3, etc. FROM TABLE

Est-ce que l'efficacité est vraiment importante dans ce cas? Je pense que SELECT * serait plus optimal en interne si vous aviez vraiment besoin de toutes les données, mais je le dis sans vraiment comprendre la base de données.

Je suis curieux de savoir quelle est la meilleure pratique dans ce cas.

PDATE: Je devrais probablement préciser que la seule situation où je voudrais vraiment vouloir faire un SELECT * est lorsque je sélectionne des données dans une table où je sais que toutes les colonnes devront toujours être extraites, même lorsque de nouvelles colonnes sont ajoutées.

Compte tenu des réponses que j'ai vues cependant, cela semble toujours être une mauvaise idée et SELECT * ne devrait jamais être utilisé pour des raisons plus techniques que celles auxquelles je pensais.

155
Dan Herbert

L'une des raisons pour lesquelles il est préférable de sélectionner des colonnes spécifiques est que cela augmente la probabilité que SQL Server puisse accéder aux données à partir d'index plutôt que d'interroger les données de la table.

Voici un article que j'ai écrit à ce sujet: La vraie raison pour laquelle les requêtes select sont une mauvaise couverture d'index

Il est également moins fragile de changer, car tout code qui consomme des données aura la même structure de données, quelles que soient les modifications que vous apportez au schéma de table à l'avenir.

158
Jon Galloway

Étant donné que votre spécification que vous êtes en sélectionnant toutes les colonnes, il y a peu de différence pour le moment. Sachez cependant que les schémas de base de données changent. Si tu utilises SELECT * vous allez ajouter de nouvelles colonnes à la table, même si, selon toute vraisemblance, votre code n'est pas prêt à utiliser ou à présenter ces nouvelles données. Cela signifie que vous exposez votre système à des modifications inattendues des performances et des fonctionnalités.

Vous voudrez peut-être rejeter cela comme un coût mineur, mais sachez que les colonnes dont vous n'avez pas besoin doivent toujours être:

  1. Lire de la base de données
  2. Envoyé sur le réseau
  3. Marqué dans votre processus
  4. (pour les technologies de type ADO) Sauvegardé dans une table de données en mémoire
  5. Ignoré et mis au rebut/ramassé

L'élément n ° 1 comporte de nombreux coûts cachés, notamment l'élimination d'un index de recouvrement potentiel, le chargement de pages de données (et la destruction de la mémoire cache du serveur), le non-respect des verrous de ligne/page/table.

Équilibrez ceci par rapport aux économies potentielles de la spécification des colonnes par rapport à * et les seules économies potentielles sont les suivantes:

  1. Le programmeur n'a pas besoin de revoir le code SQL pour ajouter des colonnes
  2. Le transport réseau du SQL est plus petit/plus rapide
  3. Heure d'analyse/validation de la requête SQL Server
  4. Cache du plan de requête SQL Server

Pour le point 1, la réalité est que vous allez ajouter/changer le code pour utiliser n'importe quelle nouvelle colonne que vous pourriez ajouter de toute façon, donc c'est un lavage.

Pour le point 2, la différence est rarement suffisante pour vous pousser vers une taille de paquet ou un nombre de paquets réseau différent. Si vous parvenez au point où le temps de transmission des instructions SQL est le problème prédominant, vous devrez probablement réduire d'abord le taux d'instructions.

Pour le poste 3, AUCUNE économie n’est réalisée grâce à l’extension du * doit quand même arriver, ce qui signifie quand même consulter le schéma de la (des) table (s). De manière réaliste, la liste des colonnes entraînera le même coût, car elles doivent être validées par rapport au schéma. En d'autres termes, c'est un lavage complet.

Pour le point 4, lorsque vous spécifiez des colonnes spécifiques, le cache de votre plan de requête peut s’agrandir mais niquement si vous utilisez différents ensembles de colonnes (ce qui n’est pas ce que vous avez spécifié). Dans ce cas, vous voulez différentes entrées de cache, car vous souhaitez utiliser différents plans en fonction des besoins.

En raison de la manière dont vous avez précisé la question, tout cela revient donc à la résilience des problèmes face aux éventuelles modifications de schéma. Si vous gravez ce schéma en ROM (ça arrive)), alors un * est parfaitement acceptable.

Cependant, mon conseil général est que vous ne devez sélectionner que les colonnes dont vous avez besoin, ce qui signifie que parfois il semblera que vous les demandiez toutes, mais les administrateurs de base de données et l'évolution du schéma signifient que de nouvelles colonnes pourraient apparaissent qui pourraient grandement affecter la requête.

Mon conseil est que vous devriez TOUJOURS CHOISIR des colonnes spécifiques. Rappelez-vous que vous faites de bonnes choses à maintes reprises, prenez donc l'habitude de bien faire les choses.

Si vous vous demandez pourquoi un schéma peut changer sans changer de code, pensez en termes de journalisation d'audit, de dates d'expiration/d'expiration et d'autres éléments similaires ajoutés par les administrateurs de bases de données pour les problèmes de conformité systémiques. Les dénormalisations pour les performances ailleurs dans le système ou les champs définis par l'utilisateur sont une autre source de modifications sournoises.

57
IDisposable

Vous ne devez sélectionner que les colonnes dont vous avez besoin. Même si vous avez besoin de toutes les colonnes, il est toujours préférable de répertorier les noms de colonne afin que le serveur SQL n'ait pas à interroger la table système pour connaître les colonnes.

En outre, votre application peut être interrompue si quelqu'un ajoute des colonnes à la table. Votre programme obtiendra des colonnes auxquelles il ne s’attendait pas et il ne sait peut-être pas comment les traiter.

En dehors de cela, si la table a une colonne binaire, la requête sera beaucoup plus lente et utilisera plus de ressources réseau.

33
Giorgi

Il y a quatre grandes raisons pour lesquelles select * est une mauvaise chose:

  1. La raison pratique la plus importante est qu’elle oblige l’utilisateur à connaître par magie l’ordre dans lequel les colonnes seront retournées. Il vaut mieux être explicite, ce qui vous protège également contre le changement de table, qui se glisse bien dans ...

  2. Si un nom de colonne que vous utilisez utilise des modifications, il est préférable de le détecter rapidement (au moment de l'appel SQL) plutôt que lorsque vous essayez d'utiliser une colonne qui n'existe plus (ou dont le nom a été modifié, etc.). )

  3. En répertoriant les noms de colonne, votre code est beaucoup plus auto-documenté et donc plus lisible.

  4. Si vous transférez sur un réseau (ou même si vous ne l'êtes pas), les colonnes dont vous n'avez pas besoin sont simplement du gaspillage.

30
pkh

Spécifier la liste des colonnes est généralement la meilleure option car votre application ne sera pas affectée si quelqu'un ajoute/insère une colonne à la table.

9
ilitirit

La spécification des noms de colonnes est nettement plus rapide - pour le serveur. Mais si

  1. les performances ne sont pas un gros problème (par exemple, il s'agit d'une base de données de contenu de sites Web contenant des centaines, voire des milliers - mais pas des millions - de lignes dans chaque table); ET
  2. votre travail consiste à créer de nombreuses petites applications similaires (par exemple, des sites Web à contenu géré gérés destinés au public) à l'aide d'un cadre commun, plutôt que de créer une application unique complexe; ET
  3. la flexibilité est importante (beaucoup de personnalisation du schéma de base de données pour chaque site);

alors vous feriez mieux de coller avec SELECT *. Dans notre cadre, l'utilisation intensive de SELECT * nous permet d'introduire dans une table un nouveau champ de contenu géré par un site Web, ce qui lui confère tous les avantages du système de gestion de contenu (versioning, workflow/approbations, etc.), tout en ne touchant que le code. quelques points, au lieu d'une douzaine de points.

Je sais que les gourous de la base de données vont me haïr pour cela - allez-y, votez contre moi -, mais dans mon monde, le temps de développement des développeurs est rare et les cycles de processeur abondants, je modifie en conséquence ce que je conserve et ce que je gaspille.

7
Herb Caudill

SELECT * est une mauvaise pratique même si la requête n'est pas envoyée sur un réseau.

  1. Si vous sélectionnez plus de données que nécessaire, la requête est moins efficace: le serveur doit lire et transférer des données supplémentaires. Cela prend donc du temps et crée une charge inutile sur le système (non seulement le réseau, comme d'autres, mais aussi les disques, les processeurs, etc.). ). En outre, le serveur n'est pas en mesure d'optimiser la requête aussi bien qu'il le pourrait (par exemple, utilisez l'index de couverture pour la requête).
  2. Après un certain temps, la structure de votre table pourrait changer, donc SELECT * renverra un ensemble de colonnes différent. Ainsi, votre application peut obtenir un jeu de données de structure inattendue et se casser quelque part en aval. La déclaration explicite des colonnes garantit que vous obtenez soit un jeu de données de structure connue, soit une erreur évidente au niveau de la base de données (comme 'colonne non trouvée').

Bien entendu, tout cela n'a pas beaucoup d'importance pour un système petit et simple.

6
VladV

En termes de performances, SELECT avec des colonnes spécifiques peut être plus rapide (pas besoin de lire toutes les données). Si votre requête utilise réellement TOUTES les colonnes, SELECT avec des paramètres explicites est toujours préféré. Toute différence de vitesse sera à la base imperceptible et quasi constante. Un jour, votre schéma changera, ce qui est une bonne assurance pour éviter les problèmes.

4
Yann Ramin

Beaucoup de bonnes raisons ont répondu ici jusqu'à présent, voici une autre qui n'a pas été mentionnée.

Nommer explicitement les colonnes vous aidera à effectuer la maintenance. À un moment donné, vous apporterez des modifications ou un dépannage et vous vous demanderez "où diable est cette colonne utilisée".

Si les noms sont énumérés explicitement, trouver chaque référence à cette colonne - dans toutes vos procédures, vues, etc. stockées - est simple. Importez simplement un script CREATE pour votre schéma de base de données et effectuez une recherche textuelle.

4
Chris Wuestefeld

Vous devriez vraiment sélectionner uniquement les champs dont vous avez besoin, et uniquement le nombre requis, c.-à-d.

SELECT Field1, Field2 FROM SomeTable WHERE --(constraints)

En dehors de la base de données, les requêtes dynamiques courent le risque d'attaques par injection et de données malformées. En général, vous contournez cela en utilisant des procédures stockées ou des requêtes paramétrées. De plus (bien que ce ne soit pas vraiment un problème), le serveur doit générer un plan d'exécution chaque fois qu'une requête dynamique est exécutée.

4
Matthew Abbott

Le problème avec "select *" est la possibilité d’apporter des données dont vous n’avez pas vraiment besoin. Lors de l'interrogation de la base de données, les colonnes sélectionnées n'ajoutent rien au calcul. Ce qui est vraiment "lourd", c'est le transfert de données vers votre client, et toute colonne dont vous n'avez pas vraiment besoin gaspille tout simplement la bande passante réseau et ajoute au temps d'attente de votre requête.

Même si vous utilisez toutes les colonnes d'un "select * ...", c'est pour le moment. Si, à l'avenir, vous modifiez la disposition de la table/vue et ajoutez des colonnes, vous apporterez celles que vous avez sélectionnées même si vous n'en avez pas besoin.

Un autre point dans lequel une instruction "select *" est incorrecte est la création de vue. Si vous créez une vue à l'aide de "select *" et que vous ajoutez ensuite des colonnes à votre table, la définition de la vue et les données renvoyées ne correspondront pas. Vous devrez donc recompiler vos vues pour qu'elles fonctionnent à nouveau.

Je sais qu'écrire un "select *" est tentant, parce que je n'aime vraiment pas spécifier manuellement tous les champs de mes requêtes, mais lorsque votre système commence à évoluer, vous verrez qu'il vaut la peine de passer plus de temps./effort en spécifiant les champs plutôt que de passer plus de temps et d'efforts à éliminer les bugs sur vos vues ou à optimiser votre application.

3
Alexandre Brasil

Bien qu'énumérer explicitement les colonnes est bon pour la performance, ne soyez pas fou.

Donc, si vous utilisez toutes les données, essayez SELECT * pour plus de simplicité (imaginez que vous ayez plusieurs colonnes et que vous fassiez une requête JOIN ... cela peut devenir affreux). Alors - mesure. Comparez avec la requête avec les noms de colonne listés explicitement.

Ne spéculez pas sur les performances, mesurez-les!

Les listes explicites sont plus utiles lorsque certaines colonnes contiennent des données volumineuses (comme le corps d'un article ou d'un article) et n'en ont pas besoin dans une requête donnée. Ensuite, en ne le renvoyant pas dans votre réponse, le serveur de base de données peut économiser du temps, de la bande passante et du débit du disque. Le résultat de votre requête sera également plus petit, ce qui convient à tout cache de requête.

3
Paweł Hajdan

définissant définitivement les colonnes, car SQL Server n'aura pas à rechercher les colonnes pour les extraire. Si vous définissez les colonnes, SQL peut ignorer cette étape.

3
Nick Berardi

Il est toujours préférable de spécifier les colonnes dont vous avez besoin. Si vous y réfléchissez une fois, SQL n'a pas à penser "wtf = *" à chaque requête. De plus, quelqu'un peut ajouter ultérieurement à la table des colonnes dont vous n'avez pas besoin dans votre requête. Dans ce cas, vous serez mieux loti en spécifiant toutes vos colonnes.

3
BrewinBombers

Select est tout aussi efficace (en termes de vélocité) si vous utilisez * ou des colonnes.

La différence concerne la mémoire, pas la vélocité. Lorsque vous sélectionnez plusieurs colonnes, SQL Server doit allouer de l'espace mémoire pour répondre à la requête, y compris toutes les données de toutes les colonnes demandées, même si vous n'en utilisez qu'une.

Ce qui compte en termes de performances, c’est le plan d’exécution qui dépend à son tour de votre clause WHERE et du nombre de JOIN, OUTER JOIN, etc.

Pour votre question, utilisez simplement SELECT *. Si vous avez besoin de toutes les colonnes, il n'y a pas de différence de performance.

2
Jorge Córdoba

Le résultat est trop énorme. Il est lent à générer et envoyer le résultat du moteur SQL au client.

Le côté client, en tant qu’environnement de programmation générique, n’est pas et ne devrait pas être conçu pour filtrer et traiter les résultats (par exemple, la clause WHERE, la clause ORDER), car le nombre de lignes peut être énorme (par exemple, des dizaines de millions de lignes).

2
kennytm

Nommer chaque colonne que vous souhaitez insérer dans votre application garantit également que votre application ne sera pas cassée si quelqu'un modifie la table, tant que vos colonnes sont toujours présentes (dans n'importe quel ordre).

2
Don

Il n’est PAS plus rapide d’utiliser des noms de champs explicites par rapport à *, si et seulement si, vous devez obtenir les données pour tous les champs.

Votre logiciel client ne doit pas dépendre de l'ordre des champs retournés, alors c'est aussi un non-sens.

Et il est possible (bien que peu probable) que vous deviez obtenir tous les champs en utilisant * car vous ne savez pas encore quels champs existent (pensez à une structure de base de données très dynamique).

L'utilisation de noms de champs explicites présente un autre inconvénient: s'ils sont nombreux et longs, la lecture du code et/ou du journal des requêtes est plus difficile.

La règle devrait donc être la suivante: si vous avez besoin de tous les champs, utilisez *, si vous n'avez besoin que d'un sous-ensemble, nommez-les explicitement.

2
user9385

Cela dépend de la version de votre serveur de base de données, mais les versions modernes de SQL peuvent mettre le plan en cache de toute façon. Je dirais aller avec ce qui est le plus maintenable avec votre code d'accès aux données.

1
Keith

L'une des raisons pour lesquelles il est préférable de définir exactement les colonnes que vous souhaitez est due aux modifications futures possibles de la structure du tableau.

Si vous lisez des données manuellement en utilisant une approche basée sur un index pour renseigner une structure de données avec les résultats de votre requête, vous aurez à l'avenir des difficultés à essayer de comprendre ce qui ne va pas.

En ce qui concerne ce qui est plus rapide, je vais laisser la parole aux autres pour leur expertise.

1
dpollock

Et rappelez-vous que si vous avez par définition une jointure interne, vous n'avez pas besoin de toutes les colonnes car les données des colonnes de jointure sont répétées.

Ce n'est pas comme si la liste des colonnes sur un serveur SQL est difficile, voire prend du temps. Vous les faites simplement glisser depuis le navigateur d’objets (vous pouvez tout faire d’un coup en faisant glisser les colonnes Word). Pour affecter durablement les performances de votre système (car cela peut réduire l’utilisation des index et empêcher l’envoi de données inutiles sur le réseau est coûteux) et il est plus probable que vous rencontriez des problèmes inattendus lorsque la base de données change vous ne voulez pas que l'utilisateur voie, par exemple), économiser juste une minute de temps de développement est à courte vue et peu professionnel.

1
HLGEM

Ce que tout le monde a dit ci-dessus, plus:

Si vous recherchez un code maintenable lisible, procédez comme suit:

SELECT foo, bar FROM widgets;

est instantanément lisible et montre l'intention. Si vous appelez, vous savez ce que vous récupérez. Si les widgets ne comportent que des colonnes foo et bar, sélectionner * signifie que vous devez toujours penser à ce que vous récupérez, assurez-vous que l'ordre est correctement mappé, etc. Cependant, si les widgets comportent plus de colonnes, et barre, votre code devient désordonné lorsque vous interrogez un caractère générique et n’utilisez que certaines parties de ce qui est renvoyé.

1
Faisal

SELECT * est nécessaire si l'on veut obtenir des métadonnées telles que le nombre de colonnes.

1
Mark Etable

Pour ajouter à ce que tout le monde a dit, si toutes vos colonnes que vous sélectionnez sont incluses dans un index, votre jeu de résultats sera extrait de l'index au lieu de rechercher des données supplémentaires à partir de SQL.

1
Mike

Comme avec la plupart des problèmes, cela dépend de ce que vous voulez réaliser. Si vous voulez créer une grille de base de données qui autorisera toutes les colonnes d'une table, "Select *" est la réponse. Toutefois, si vous n'avez besoin que de certaines colonnes et que l'ajout ou la suppression de colonnes de la requête est peu fréquent, spécifiez-les individuellement.

Cela dépend également de la quantité de données que vous souhaitez transférer du serveur. Si l’une des colonnes est définie comme mémo, graphique, blob, etc. et que vous n’avez pas besoin de cette colonne, vous feriez mieux de ne pas utiliser "Select *" ou vous obtiendrez tout un tas de données que vous n’aurez pas. vouloir et votre performance pourrait en souffrir.

1
Mark

Que l'efficacité soit ou non importante dépend beaucoup de la taille de vos jeux de données de production (et de leur taux de croissance). Si vos ensembles de données ne sont pas aussi volumineux et qu'ils ne vont pas se développer aussi rapidement, la sélection de colonnes individuelles ne présente pas un avantage considérable en termes de performances.

Avec des ensembles de données plus volumineux et des taux de croissance de données plus rapides, l’avantage en performances devient de plus en plus important.

Pour voir graphiquement s'il y a une différence ou non, je suggérerais d'utiliser l'analyseur de requête pour voir le plan d'exécution de la requête pour un SELECT * et son équivalent SELECT col1, col2, etc. Cela devrait vous indiquer laquelle des deux requêtes est la plus efficace. Vous pouvez également générer des données de test sur différents volumes afin d’en connaître le minutage.

0
Scott Lawrence

Je vais devoir claquer pour ça, mais je fais un select * car presque toutes mes données sont retransmises à partir de vues SQL Server qui précombinent les valeurs nécessaires de plusieurs tables en une seule vue facile d'accès.

Je souhaite ensuite que toutes les colonnes de la vue ne changent pas lorsque de nouveaux champs sont ajoutés aux tables sous-jacentes. Cela a l’avantage supplémentaire de me permettre de changer la provenance des données. FieldA dans la vue peut être calculé en même temps, puis je peux le changer pour qu'il soit statique. De toute façon, la vue me fournit FieldA.

La beauté de ceci est qu’elle permet à ma couche de données d’obtenir des jeux de données. Il les transmet ensuite à mon BL, qui peut ensuite créer des objets à partir d’eux. Mon application principale ne connaît et n'interagit qu'avec les objets. J'autorise même mes objets à s'auto-créer lorsqu'ils sont transmis à un serveur de données.

Bien sûr, je suis le seul développeur, donc ça aide aussi :)

0
klkitchens

Définissez absolument les colonnes que vous voulez sélectionner à chaque fois. Il n'y a aucune raison de ne pas le faire et l'amélioration des performances en vaut la peine.

Ils n'auraient jamais dû donner l'option "SELECT *"

0
cazlab

Si vous avez besoin de chaque colonne, utilisez simplement SELECT *, mais n'oubliez pas que l'ordre peut potentiellement changer. Lorsque vous consommez les résultats, accédez-y par nom et non par index.

J'ignorerais les commentaires sur la façon dont * doit aller chercher la liste - il y a des chances que l'analyse et la validation des colonnes nommées soient égales au temps de traitement, sinon plus. Ne pas optimiser prématurément ;-)

0
DamienG

La principale différence entre les deux réside dans la quantité de données échangées. Tous les arguments relatifs à la différence de temps sont fondamentalement erronés dans la mesure où "select *" et "select col1, ..., colN" entraînent le même travail relatif que le moteur de base de données. Toutefois, la transmission de 15 colonnes par ligne contre 5 colonnes par ligne correspond à une différence de 10 colonnes.

0
Jeff Hubbard

En termes d'efficacité d'exécution, je ne suis conscient d'aucune différence significative. Mais pour l'efficacité des programmeurs, j'écrirais les noms des champs car

  • Vous connaissez l'ordre si vous devez indexer par numéro ou si votre pilote se comporte de manière amusante sur les valeurs d'objets blob et vous avez besoin d'un ordre précis.
  • Vous ne lisez que les champs dont vous avez besoin, si vous deviez en ajouter d'autres
  • Vous obtenez une erreur SQL si vous mal orthographiez ou renommez un champ, pas une valeur vide d'un jeu d'enregistrements/ligne
  • Vous pouvez mieux lire ce qui se passe.
0
Erik

Je vois que plusieurs personnes semblent penser qu'il faut beaucoup plus de temps pour spécifier les colonnes. Comme vous pouvez faire glisser la liste des colonnes à partir du navigateur d’objets, il faut peut-être une minute supplémentaire pour spécifier des colonnes (c’est-à-dire si vous avez beaucoup de colonnes et que vous devez passer du temps à les placer sur des lignes séparées) dans la requête. Pourquoi les gens pensent-ils que cela prend tellement de temps?

0
HLGEM

Je recommande toujours de spécifier les colonnes dont vous avez besoin, juste au cas où votre schéma changerait et que vous n'avez pas besoin de la colonne supplémentaire.

De plus, qualifiez les noms de colonne avec le nom de la table. Ceci est critique lorsque la requête contient des jointures. Sans les qualifications de table, il peut être difficile de se rappeler quelle colonne provient de quelle table, et ajouter une colonne portant le même nom à l'une des autres tables peut rompre votre requête.

0
mxsscott

Performance sage j'ai vu des commentaires que les deux sont égaux. mais l'aspect de la convivialité il y a quelques + et - de

Lorsque vous utilisez un (sélectionnez *) dans une requête et que certains modifient la table et ajoutent de nouveaux champs qui ne sont pas nécessaires pour la requête précédente, cela représente une surcharge inutile. Et si le champ nouvellement ajouté est un blob ou un champ d’image ??? votre temps de réponse à la requête va alors être vraiment lent.

D'autre part, si vous utilisez a (sélectionnez col1, col2, ..) et que la table est modifiée et que de nouveaux champs sont ajoutés et que ces champs sont nécessaires dans le jeu de résultats, vous devez toujours modifier votre requête de sélection après modification de la table.

Mais je suggère de toujours utiliser select col1, col2, ... dans vos requêtes et de modifier la requête si la table est modifiée ultérieurement ...

0
Lahiru Cooray

Il est particulièrement important pour les performances de ne pas utiliser select * lorsque vous avez une jointure car, par définition, au moins deux champs contiennent les mêmes données. Vous ne voulez pas gaspiller les ressources du réseau en envoyant des données inutiles du serveur de base de données à l'application ou au serveur Web. Cela peut sembler plus facile d’utiliser select * mais c’est une mauvaise pratique. Comme il est facile de faire glisser les noms de colonne dans la requête, faites-le simplement.

Un autre problème qui se produit lors de l’utilisation de select * est qu’il existe des idiots qui choisissent d’ajouter de nouveaux champs au milieu du tableau (ce qui est toujours une mauvaise pratique). Si vous utilisez select * comme base pour une insertion, votre ordre de colonne peut soudainement être modifié. mal et vous pouvez essayer d'insérer le numéro de sécurité sociale dans les honoraires (une somme d'argent qu'un orateur peut être payé pour choisir un exemple non aléatoire), ce qui pourrait être une très mauvaise chose pour l'intégrité des données. Même si la sélection ne constitue pas une insertion, le client a mauvaise mine lorsque les données sont soudainement en ordre de défilement dans le rapport ou la page Web.

Je pense ne penser à aucune circonstance lorsque vous utilisez select * est préférable à une liste de colonnes. Vous pensez peut-être qu'il est plus facile à gérer, mais en réalité, ce n'est pas le cas et votre application sera ralentie sans raison, lorsque des champs inutiles sont ajoutés aux tables. Vous devrez également faire face au problème de la correction de problèmes qui n’auraient pas été résolus si vous aviez utilisé une liste de colonnes. Le temps que vous enregistrez, sans ajouter de colonne, est épuisé.

0
HLGEM

hé, sois pratique. utilisez select * lors du prototypage et sélectionnez des colonnes spécifiques lors de l'implémentation et du déploiement. du point de vue du plan d'exécution, les deux sont relativement identiques sur les systèmes modernes. Cependant, la sélection de colonnes spécifiques limite la quantité de données à extraire du disque, stockées en mémoire et envoyées sur le réseau.

en fin de compte, le meilleur plan consiste à sélectionner des colonnes spécifiques.

0
siculars

Tenez également compte des changements. Aujourd'hui, Select * ne sélectionne que les colonnes dont vous avez besoin, mais demain, il pourra également sélectionner la colonne varbinary (MAX) que je viens d'ajouter sans vous le dire, et vous récupérez également tous les 3.18 gigaoctets de données binaires qui n'étaient pas dans la table hier.

0
Michael Stum

Permet de penser à ce qui est le plus rapide. Si vous ne pouvez sélectionner que les données dont vous avez besoin, c'est plus rapide. Toutefois, lors des tests, vous pouvez extraire toutes les données pour déterminer quelles données peuvent être filtrées en fonction des besoins de l'entreprise.

0
mikedopp

Il existe des cas où SELECT * convient à des fins de maintenance, mais il convient généralement de l'éviter.

Ce sont des cas spéciaux comme les vues ou les procédures stockées dans lesquels vous souhaitez que les modifications des tables sous-jacentes se propagent sans avoir à modifier toutes les vues et procédures stockées qui utilisent la table. Même dans ce cas, cela peut entraîner des problèmes, comme dans le cas où vous avez deux vues jointes. Une table sous-jacente change et la vue est maintenant ambiguë car les deux tables ont une colonne du même nom. (Notez que cela peut arriver chaque fois que vous ne qualifiez pas toutes vos colonnes avec des préfixes de table). Même avec des préfixes, si vous avez une construction comme:

SELECT A ., B. - Vous pouvez avoir des problèmes lorsque le client a maintenant des difficultés à sélectionner le bon champ.

En général, je n’utilise pas SELECT * à moins que je ne prenne une décision de conception consciente et que les risques associés soient faibles.

0
Cade Roux

Le SELECT *pourrait être ok si vous aviez réellement besoin de toutes les colonnes - mais vous devriez quand même les lister individuellement. Vous ne devriez certainement pas sélectionner toutes les lignes d'une table, même si l'application et la base de données se trouvent sur le même serveur ou le même réseau. Le transfert de toutes les lignes prendra du temps, en particulier à mesure que le nombre de lignes augmente. Vous devriez avoir au moins une clause where filtrant les résultats et/ou une page de résultats pour ne sélectionner que le sous-ensemble de lignes à afficher. Plusieurs outils ORM existent en fonction du langage d'application que vous utilisez pour vous aider à interroger et à paginer le sous-ensemble de données dont vous avez besoin. Par exemple, dans .NET, Linq to SQL, Entity Framework et nHibernate vont vous aider.

0
bkaid

Utilisez des noms de champs spécifiques. Ainsi, si quelqu'un modifie la table sur vous, vous n'obtenez pas de résultats inattendus. Sur le sujet: TOUJOURS spécifier les noms de champs lors de l'insertion. Par conséquent, si vous devez ajouter une colonne ultérieurement, vous n'avez pas besoin de revenir en arrière et de corriger votre programme et de modifier la base de données en même temps dans la version de production.

0
stu

Si vous êtes préoccupé par la vitesse, veillez à utiliser des instructions préparées. Sinon, je suis avec ilitirit que les changements sont ceux contre lesquels vous vous protégez.

/ Allan

0
Allan Wind

Je trouve que la liste des noms de colonnes est particulièrement importante si d'autres développeurs sont susceptibles de travailler avec le code ou si la base de données est susceptible de changer, de sorte que vous obtenez toujours des données cohérentes.

0
Sam Cogan

Ceci est un ancien post, mais toujours valable. Pour référence, j'ai une requête très compliquée composée de:

  • 12 tables
  • 6 jointures à gauche
  • 9 jointures intérieures
  • 108 colonnes au total sur les 12 tableaux
  • J'ai seulement besoin de 54 colonnes
  • Une clause Order By de 4 colonnes

Lorsque j'exécute la requête à l'aide de Select *, il faut en moyenne 2869ms. Lorsque j'exécute la requête en utilisant Select, il faut en moyenne 1513ms.

Le nombre total de lignes renvoyées est de 13 949.

Il ne fait aucun doute que choisir des noms de colonne signifie des performances plus rapides par rapport à Select *.

Pour interroger directement la base de données (par exemple, à l'aide d'une invite sqlplus ou via un outil d'administration de base de données), sélectionnez * c'est généralement bien - cela vous évitera d'avoir à écrire toutes les colonnes.

En revanche, dans le code de l’application, il est préférable d’énumérer les colonnes. Cela présente plusieurs avantages:

  • Le code est plus clair
  • Vous saurez l'ordre dans lequel les résultats sont renvoyés (cela peut être important ou non pour vous)
0
Morikal

Cela dépend vraiment de vos paramètres et de votre objectif:

  1. Si vous avez 250 colonnes et que vous voulez (en effet) les sélectionner toutes, utilisez select * si vous voulez rentrer chez vous le jour même :)
  2. Si votre codage a besoin de souplesse et que la table dans le besoin est petite, sélectionnez à nouveau * pour vous aider à coder plus rapidement et à le conserver plus facilement.
  3. Si vous souhaitez une ingénierie et des performances robustes:
    • écrivez vos noms de colonnes s'il ne s'agit que de quelques-uns, ou
    • écrire un outil qui vous permet de sélectionner/générer facilement vos noms de colonne

En règle générale, lorsque j'ai besoin de sélectionner toutes les colonnes, j'utilise "select *" sauf si j'ai une raison très spécifique de faire autrement (en plus, je pense que c'est plus rapide pour les tableaux avec beaucoup, beaucoup de colonnes)

Enfin, comment voulez-vous que l’ajout ou la suppression d’une colonne dans la table affecte votre code ou sa maintenance?

0
Notitze