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

166

J'ai entendu dire que SELECT *c'est généralement une mauvaise pratique à utiliser lors de l'écriture de commandes SQL, car elle est plus efficace pour les SELECTcolonnes dont vous avez spécifiquement besoin.

Si j'ai besoin de SELECTchaque colonne d'une table, dois-je utiliser

SELECT * FROM TABLE

ou

SELECT column1, colum2, column3, etc. FROM TABLE

L'efficacité compte-t-elle vraiment dans ce cas? Je pense que ce SELECT *serait plus optimal en interne si vous avez vraiment besoin de toutes les données, mais je dis cela sans réelle compréhension de la base de données.

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

MISE À JOUR: Je devrais probablement préciser que la seule situation où je vraiment envie de faire unSELECT * est quand je sélectionne des données d'une table où je sais que toutes les colonnes auront toujours besoin d' être récupérées, 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 beaucoup plus techniques auxquelles j'ai jamais pensé.

Dan Herbert
la source

Réponses:

168

L'une des raisons pour lesquelles la sélection de colonnes spécifiques est préférable est qu'elle 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 de sélection sont une mauvaise couverture d'index

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

Jon Galloway
la source
3
+1 pour cela. Si toutes les colonnes référencées existent dans un seul index (un «index couvrant»), vous avez frappé l'or.
Ian Nelson
22
ce n'est pas la réponse à sa question - "Si j'ai besoin de SÉLECTIONNER chaque colonne dans une table, ..." - dans ce cas, * vs col1, .., coln n'a pas d'importance (mais c'est le cas pour le temps du programmeur, puisque * est plus court!).
Matt Rogish
3
Cela reste important, car la liste de sélection est une forme de contrat, surtout si le SQL est dans une procédure stockée.
Eric Z Beard
4
Bien que ce que Jon dit soit tout à fait correct, et un point très valable, je dois admettre que la question ASKED est de savoir s'ils sont déjà ceux qui demandent toutes les colonnes. En raison de cette partie de la question, le vrai problème est la fragilité face aux changements de schéma.
IDisposable le
1
@MattRogish monsieur vous l'avez bien compris, y a-t-il une différence de performance entre ces deux méthodes (* vsall_column_names) alors que nous avons des milliers de lignes et que nous effectuons SELECT avec index (dans la clause WHERE) ??
santosh
59

Compte tenu de votre cahier des charges que vous êtes sélectionnez toutes les colonnes, il y a peu de différence à ce moment . Sachez cependant que les schémas de base de données changent. Si vous utilisez, 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 changements de performances et de fonctionnalités inattendus.

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 à partir de la base de données
  2. Envoyé sur le réseau
  3. Marshalled dans votre processus
  4. (pour les technologies de type ADO) Enregistré dans une table de données en mémoire
  5. Ignoré et mis au rebut / ramassé

L'élément n ° 1 a de nombreux coûts cachés, y compris l'élimination de certains index de couverture potentiels, provoquant des chargements de pages de données (et la destruction du cache du serveur), entraînant des verrous de ligne / page / table qui pourraient être évités autrement.

Comparez cela aux économies potentielles de la spécification des colonnes par rapport à an *et les seules économies potentielles sont:

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

Pour l'élément 1, la réalité est que vous allez ajouter / modifier du code pour utiliser toute nouvelle colonne que vous pourriez ajouter de toute façon, donc c'est un lavage.

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

Pour l'élément 3, il n'y a AUCUNE économie car l'expansion du *doit se produire de toute façon, ce qui signifie de toute façon consulter le schéma des tables. 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 l'élément 4, lorsque vous spécifiez des colonnes spécifiques, le cache de votre plan de requête peut devenir plus volumineux, mais uniquement si vous avez affaire à différents ensembles de colonnes (ce qui n'est pas ce que vous avez spécifié). Dans ce cas, vous voulez des entrées de cache différentes car vous voulez des plans différents selon vos besoins.

Donc, tout cela se résume, en raison de la façon dont vous avez spécifié la question, au problème de résilience face à d'éventuelles modifications de schéma. Si vous gravez ce schéma dans la ROM (cela arrive), alors un *est parfaitement acceptable.

Cependant, ma directive générale 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 DBA et l'évolution du schéma signifient que de nouvelles colonnes peuvent apparaître, ce qui pourrait grandement affecter la requête. .

Mon conseil est que vous devez TOUJOURS CHOISIR des colonnes spécifiques . N'oubliez pas que vous devenez bon dans ce que vous faites encore et encore, alors prenez l'habitude de le faire correctement.

Si vous vous demandez pourquoi un schéma peut changer sans changement de code, pensez à la journalisation d'audit, aux dates d'effet / d'expiration et à d'autres éléments similaires qui sont ajoutés par les administrateurs de base de données pour des problèmes de conformité systématiques. Une autre source de changements sournois est la dénormalisation des performances ailleurs dans le système ou dans les champs définis par l'utilisateur.

IDisposable
la source
3
"la réalité est que vous allez ajouter / modifier du code pour utiliser toute nouvelle colonne que vous pourriez ajouter de toute façon, donc c'est un lavage." -Seulement si vous lisez manuellement chaque colonne par nom dans votre code. Si vous utilisez le mappage automatique, ce n'est pas le cas et ce problème devient important.
Josh Noe
36

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 colonnes afin que le serveur SQL n'ait pas à interroger la table système pour les colonnes.

En outre, votre application peut être interrompue si quelqu'un ajoute des colonnes à la table. Votre programme recevra également des colonnes auxquelles il ne s'attendait pas et il ne saura 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.

Giorgi
la source
6
Aha donc en utilisant * vous ajoutez du travail supplémentaire pour la base de données. Ok, c'est une raison pour laquelle je n'avais pas pensé.
Ankur le
1
+1 pour les risques de casser / attraper des erreurs tôt. Je pense que la discussion sur l'efficacité est valable mais YAGNI.
nailitdown le
6
Le serveur SQL n'aurait-il pas besoin de valider ou de vérifier si "col1" est de toute façon dans la table spécifiée, c'est-à-dire la table système de requête?
Patrick le
3
Le plus gros impact sur les performances est probablement lié à l'indexation. Si la colonne que vous recherchez fait partie de l'index utilisé pour trouver les données, le serveur les récupérera directement, si vous effectuez une sélection *, il devra probablement faire ce que l'on appelle une recherche de signets, ce qui nécessite un supplément. scannez pour trouver le reste des données sous-jacentes, dont vous n'avez peut-être même pas besoin.
Cobusve
3
@Patrick - Sur place. Beaucoup de bonnes raisons d'éviter * mais ce n'est pas l'une d'entre elles.
Martin Smith
31

Il y a quatre grandes raisons pour lesquelles c'est select *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 renvoyées. Il vaut mieux être explicite, ce qui vous protège également contre le changement de table, qui s'enchaîne bien en ...

  2. Si un nom de colonne que vous utilisez change, il est préférable de l'attraper tôt (au moment de l'appel SQL) plutôt que lorsque vous essayez d'utiliser la colonne qui n'existe plus (ou dont le nom a été changé, etc. )

  3. La liste des noms de colonnes rend votre code beaucoup plus auto-documenté, et donc probablement 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 ne sont que du gaspillage.

pkh
la source
7
"La raison pratique la plus significative est que cela oblige l'utilisateur à connaître par magie l'ordre dans lequel les colonnes seront renvoyées." Je ne vois pas en quoi c'est un problème. Dans n'importe quel client DB moderne, vous lisez les colonnes par nom et non par ordre.
Josh Noe
J'ai tendance à exécuter mon SQL via une interface C, donc je ne saurais pas vraiment quel est l'état de l'art des "clients DB". Mais je pense que le type de client dont vous parlez fait probablement de la magie non standard non SQL. (par exemple, dans SQLite, interroger sqlite3_master pour savoir comment changer votre *en un ensemble de noms.)
pkh
Et plus loin, combien de personnes écrivent du code dans des applications modernes qui utilisent soit l'index des noms de colonnes? La plupart des gens utilisent sûrement une sorte de mappeur et tout un tas de cache pour les données qui sont autorisées à être périmées. Personnellement, écrivez d'abord le code, puis inquiétez-vous si vous rencontrez des problèmes de performances plus tard.
Colin Wiseman
10

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

ilitirit
la source
7

La spécification des noms de colonne 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 site Web avec 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 gérés par le contenu destinés au public) en utilisant 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 vous en tenir à SELECT *. Dans notre cadre, une utilisation intensive de SELECT * nous permet d'introduire un nouveau champ de contenu géré de site Web dans une table, lui donnant tous les avantages du CMS (versionnage, workflow / approbations, etc.), tout en touchant uniquement le code à un quelques points, au lieu de quelques dizaines de points.

Je sais que les gourous de la DB vont me détester pour cela - allez-y, votez-moi - mais dans mon monde, le temps des développeurs est rare et les cycles de processeur sont abondants, donc j'ajuste en conséquence ce que je conserve et ce que je gaspille.

Herbe Caudill
la source
1
Cela rend également les ORM beaucoup plus simples à utiliser. Lorsque les requêtes sont construites en passant un objet de création de requête, on ne sait pas nécessairement quelles colonnes étaient requises par quelles autres parties du code (vérifications d'autorisation, qu'est-ce que vous avez). Donc, pour limiter les colonnes, il faudrait enquêter à chaque fois qu'une requête doit être écrite. C'est inutile, OMI. Lorsque les requêtes s'avèrent lentes (logs!), On peut les améliorer.
bytepusher
6

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

  1. La sélection de plus de données que ce dont vous avez besoin rend la requête moins efficace - le serveur doit lire et transférer des données supplémentaires, donc cela prend du temps et crée une charge inutile sur le système (non seulement le réseau, comme d'autres l'ont mentionné, mais aussi le disque, le processeur, etc. ). En outre, le serveur ne peut pas optimiser la requête aussi bien qu'il le pourrait (par exemple, utiliser un index de couverture pour la requête).
  2. Après un certain temps, la structure de votre table peut changer, donc SELECT * renverra un ensemble de colonnes différent. Ainsi, votre application peut obtenir un ensemble de données de structure inattendue et se briser quelque part en aval. Le fait de déclarer explicitement les colonnes garantit que vous obtenez soit un ensemble de données de structure connue, soit une erreur claire au niveau de la base de données (comme «colonne non trouvée»).

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

VladV
la source
4

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 vraiment TOUTES les colonnes, SELECT avec des paramètres explicites est toujours préféré. Toute différence de vitesse sera fondamentalement imperceptible et quasi constante. Un jour, votre schéma changera, et c'est une bonne assurance pour éviter les problèmes dus à cela.

Yann Ramin
la source
Vous vous trompez sur l'invisible car d'après les vérifications que j'ai effectuées avec plusieurs bases de données, il était clair que la sélection de chaque colonne, même si toutes, est beaucoup plus rapide. Dans certains cas, c'était trois fois plus rapide.
shahar eldad
4

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

Nommer explicitement les colonnes vous aidera avec la maintenance sur la route. À un moment donné, vous allez apporter des modifications ou effectuer un dépannage, et vous vous demandez «où diable cette colonne est-elle utilisée».

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

Chris Wuestefeld
la source
3

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

Nick Berardi
la source
Ceci est: 1) non pertinent, car SQL Server doit référencer le schéma de table de toute façon (pour valider les noms de colonne ou pour rechercher les noms de colonne valides connus) 2) Non pertinent pour la question posée, où toutes les colonnes sont référencées. Le seul problème ASKED est la fragilité avec les changements de schéma.
IDisposable le
Voté contre, car il faut quand même valider les colonnes.
John Gibb
3

Il est toujours préférable de spécifier les colonnes dont vous avez besoin, si vous y pensez une fois, SQL n'a pas à penser "wtf is *" à chaque fois que vous interrogez. En plus de cela, quelqu'un plus tard peut ajouter des colonnes à la table dont vous n'avez en fait pas besoin dans votre requête et vous serez mieux dans ce cas en spécifiant toutes vos colonnes.

BrewinBombers
la source
1
Ce n'est pas vrai: le serveur SQL doit toujours analyser chaque colonne et voir si elle existe dans les catalogues, alors qu'il sait que "*" le fait (et oui, * est étendu à toutes les cols). Quoi qu'il en soit, il est trivialement facile pour le SGBD de faire l'un ou l'autre (à moins que vous n'ayez 24000 colonnes), alors je parie que c'est la même chose dans les deux cas
Matt Rogish
Je pense que le meilleur point qu'il manque beaucoup et, malheureusement, cette réponse ne concerne que secondairement, c'est que si des changements de schéma / table se produisent (c'est-à-dire de nouvelles colonnes ajoutées), cela ne cassera pas les choses.
Sean Hanley le
1
C'est un lavage complet car la recherche des colonnes pour l'extension * revient à valider les noms de colonnes fournis.
IDisposable le
3

Le problème avec "select *" est la possibilité d'apporter des données dont vous n'avez pas vraiment besoin. Pendant la requête de base de données réelle, les colonnes sélectionnées n'ajoutent pas vraiment au calcul. Ce qui est vraiment «lourd», c'est le transport des données vers votre client, et toute colonne dont vous n'avez pas vraiment besoin gaspille simplement la bande passante du réseau et ajoute au temps que vous attendez que votre requête soit renvoyée.

Même si vous utilisez toutes les colonnes provenant d'un "select * ...", c'est juste pour le moment. Si à l'avenir vous modifiez la disposition de la table / vue et ajoutez plus de colonnes, vous commencerez à les intégrer dans vos sélections même si vous n'en avez pas besoin.

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

Je sais qu'écrire un "select *" est tentant, car je n'aime vraiment pas spécifier manuellement tous les champs de mes requêtes, mais lorsque votre système commencera à évoluer, vous verrez que cela vaut la peine de passer ce temps supplémentaire / effort pour spécifier les champs plutôt que de passer beaucoup plus de temps et d'efforts à supprimer les bogues sur vos vues ou à optimiser votre application.

Alexandre Brasil
la source
Le point sur les VUES est très important. Non seulement vous n'obtiendrez pas toutes les colonnes si vous ajoutez des colonnes au tableau (malgré ce que * vous ferait penser), mais elles pourraient même ne pas correspondre à la disposition réelle du tableau.
Euro Micelli
3

Bien que lister explicitement les colonnes soit bon pour les performances, ne soyez pas fou.

Donc, si vous utilisez toutes les données, essayez SELECT * pour plus de simplicité (imaginez avoir de nombreuses colonnes et faire une requête JOIN ... peut devenir horrible). Ensuite - mesurez. Comparez avec la requête avec les noms de colonne répertoriés explicitement.

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

La liste explicite est plus utile lorsque vous avez une colonne contenant des données volumineuses (comme le corps d'un article ou d'un article) et que vous n'en avez pas besoin dans une requête donnée. Ensuite, en ne le renvoyant pas dans votre serveur de base de données de réponse, vous pouvez gagner 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.

Paweł Hajdan
la source
3

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

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 mal formées. En général, vous contournez cela à l'aide de procédures stockées ou de 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.

Matthew Abbott
la source
"le serveur doit générer un plan d'exécution chaque fois qu'une requête dynamique est exécutée" ce qui, je suppose, ralentit la requête. Merci.
Ankur le
Les problèmes de performances liés à l'utilisation de SQL dynamique ne seraient probablement réalisés que dans des scénarios de charge très élevée, Sql Server est assez bon pour gérer efficacement les plans de requête.
Matthew Abbott
2

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

La différence concerne la mémoire, pas la vitesse. Lorsque vous sélectionnez plusieurs colonnes, SQL Server doit allouer de l'espace mémoire pour vous servir la requête, y compris toutes les données de toutes les colonnes que vous avez demandées, même si vous n'utilisez qu'une seule d'entre elles.

Ce qui compte en termes de performances, c'est le plan d'exécution qui à son tour dépend fortement 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 performances.

Jorge Córdoba
la source
2

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

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

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

Un autre inconvénient de l'utilisation de noms de champs explicites est que 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.

user9385
la source
2

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, étant un environnement de programmation générique, n'est pas et ne doit 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).

KennyTM
la source
Donc, si vous aviez besoin d'utiliser toutes les différentes colonnes, ce serait bien ... et si votre base de données et votre application sont à nouveau assis sur le même serveur, cela ne fait pas beaucoup de différence?
Ankur le
@Ankur: Même sur le même serveur, il y a des frais pour transmettre des données via l'interface de la base de données.
kennytm
2

Nommer chaque colonne que vous prévoyez d'obtenir dans votre application garantit également que votre application ne se cassera pas si quelqu'un modifie la table, tant que vos colonnes sont toujours présentes (dans n'importe quel ordre).

Don
la source
1

Cela dépend de la version de votre serveur DB, mais les versions modernes de SQL peuvent mettre en cache le plan dans les deux cas. Je dirais que ce qui est le plus maintenable avec votre code d'accès aux données.

Keith
la source
1

Une des raisons pour lesquelles il est préférable de préciser exactement quelles colonnes vous voulez est en raison de possibles changements futurs dans la structure du tableau.

Si vous lisez manuellement des données en utilisant une approche basée sur un index pour remplir une structure de données avec les résultats de votre requête, alors à l'avenir, lorsque vous ajoutez / supprimez une colonne, vous aurez des maux de tête en essayant de comprendre ce qui n'a pas fonctionné.

Quant à ce qui est plus rapide, je m'en remettrai à d'autres pour leur expertise.

dpollock
la source
1

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

Cela dépend également de la quantité de données que vous souhaitez transférer depuis le 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 "Sélectionner *" ou vous obtiendrez un tas de données que vous n'avez pas veulent et vos performances pourraient en souffrir.

marque
la source
1

Pour ajouter à ce que tout le monde a dit, si toutes les 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.

Mike
la source
1

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

Marquer Etable
la source
1

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

Si vous recherchez un code maintenable lisible, faites quelque chose comme:

SELECT foo, barre FROM widgets;

est instantanément lisible et montre l'intention. Si vous passez cet appel, vous savez ce que vous récupérez. Si les widgets n'ont que des colonnes foo et bar, alors sélectionner * signifie que vous devez toujours penser à ce que vous récupérez, confirmer que l'ordre est correctement mappé, etc. Cependant, si les widgets ont plus de colonnes mais que vous n'êtes intéressé que par foo et bar, alors votre code devient désordonné lorsque vous recherchez un caractère générique et n'utilisez qu'une partie de ce qui est retourné.

Faisal
la source
1

Et rappelez-vous que si vous avez une jointure interne par définition, 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 dans le serveur SQl était difficile ou même chronophage. Vous les faites simplement glisser depuis le navigateur d'objets (vous pouvez tout obtenir en une seule fois en les faisant glisser à partir des colonnes de mots). Pour mettre un impact permanent sur les performances de votre système (parce que cela peut réduire l'utilisation des index et parce que l'envoi de données inutiles sur le réseau est coûteux) et rendre plus probable que vous ayez des problèmes inattendus lorsque la base de données change (parfois des colonnes sont ajoutées que vous ne voulez pas que l'utilisateur voie par exemple) juste pour gagner moins d'une minute de temps de développement est à courte vue et non professionnel.

HLGEM
la source
1

En termes de performances, j'ai vu des commentaires selon lesquels les deux sont égaux. mais aspect convivialité il y a des + et des -

Lorsque vous utilisez un (select *) dans une requête et si quelqu'un modifie la table et ajoute de nouveaux champs qui n'ont pas besoin pour la requête précédente, c'est une surcharge inutile. Et si le champ nouvellement ajouté est un blob ou un champ d'image ??? le temps de réponse de votre requête sera alors très lent.

D'autre part, si vous utilisez un (sélectionnez col1, col2, ..) et si la table est modifiée et ajouté de nouveaux champs et si ces champs sont nécessaires dans le jeu de résultats, vous devez toujours éditer votre requête de sélection après la 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 plus tard ...

Lahiru Cooray
la source
0

Définissez absolument les colonnes que vous souhaitez SELECT à 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 *"

cazlab
la source
0

Si vous avez besoin de chaque colonne, utilisez simplement SELECT * mais rappelez-vous que l'ordre peut potentiellement changer, alors 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 - les chances sont que l'analyse et la validation des colonnes nommées sont égales au temps de traitement sinon plus. N'optimisez pas prématurément ;-)

DamienG
la source
0

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

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

hé, soyez 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 qui doivent être extraites 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.

siculars
la source