select * vs select column

Si j’ai juste besoin de 2/3 colonnes et que j’interroge SELECT * au lieu de fournir ces colonnes dans la requête de sélection, y a-t-il une dégradation des performances concernant plus / moins d’E / S ou de mémoire?

La surcharge du réseau peut être présente si je sélectionne * sans besoin.

Mais dans une opération de sélection, le moteur de firebase database extrait-t-il toujours le tuple atomique du disque ou extrait-il uniquement les colonnes demandées dans l’opération de sélection?

S’il tire toujours un tuple, alors le surcoût d’E / S est le même.

Dans le même temps, il pourrait y avoir une consommation de mémoire pour éliminer les colonnes demandées du tuple, s’il tire un tuple.

Si c’est le cas, select someColumn aura plus de mémoire que celui de select *

Il tire toujours un tuple (sauf dans les cas où la table a été segmentée verticalement – divisée en colonnes), donc, pour répondre à la question que vous avez posée, cela n’a pas d’importance du sharepoint vue de la performance. Cependant, pour de nombreuses autres raisons, (ci-dessous), vous devez toujours sélectionner spécifiquement les colonnes de votre choix, par nom.

Il tire toujours un tuple, car (dans tous les fournisseurs de SGBDR que je connais, la structure de stockage sur disque sous-jacente pour tout (y compris les données de table) est basée sur des pages d’E / S définies (dans SQL Server, par exemple). kilo-octets.Et chaque lecture / écriture est effectuée par page. C’est-à-dire que chaque écriture ou lecture est une page complète de données.

En raison de cette contrainte structurelle sous-jacente, chaque ligne de données d’une firebase database doit toujours se trouver sur une seule et unique page. Il ne peut pas s’étendre sur plusieurs pages de données (sauf pour les objects spéciaux tels que les tâches de couleur, où les données de tâches réelles sont stockées dans des segments de page distincts, et la colonne de ligne de tableau n’obtient alors qu’un pointeur …). Mais ces exceptions ne sont que des exceptions et ne s’appliquent généralement pas sauf dans des cas particuliers (pour des types de données particuliers ou certaines optimisations pour des circonstances particulières).
Même dans ces cas particuliers, en général, la ligne de données de la table elle-même (qui contient le pointeur sur les données réelles du Blob, ou autre), doit être stockée sur une seule page IO …

EXCEPTION. Le seul endroit où Select * est OK, se trouve dans la sous-requête après une clause de prédicat Exists ou Not Exists , comme dans:

  Select colA, colB From table1 t1 Where Exists (Select * From Table2 Where column = t1.colA) 

EDIT: Pour répondre au commentaire de @Mike Sherer, oui c’est vrai, à la fois techniquement, avec un peu de définition pour votre cas particulier, et esthétiquement. Tout d’abord, même lorsque l’ensemble des colonnes demandées est un sous-ensemble de celles stockées dans un index, le processeur de requêtes doit récupérer toutes les colonnes stockées dans cet index, pas seulement celles demandées, pour les mêmes raisons. les pages et les données d’index sont stockées dans IO Pages, tout comme les données de tableau. Donc, si vous définissez “tuple” pour une page d’index comme l’ensemble des colonnes stockées dans l’index, l’instruction est toujours vraie.
et la déclaration est vraie du sharepoint vue esthétique car il s’agit de récupérer des données en fonction de ce qui est stocké dans la page d’E / S, et non de ce que vous demandez, que vous accédiez à la page d’E / S de la table de base ou à un index. Page d’E / S.

Pour d’autres raisons de ne pas utiliser Select * , voir Pourquoi SELECT * considéré comme dangereux? :

Il y a plusieurs raisons pour lesquelles vous ne devriez jamais (jamais) utiliser SELECT * dans le code de production:

  • Comme vous ne donnez à votre firebase database aucun indice sur ce que vous voulez, il faudra d’abord vérifier la définition de la table afin de déterminer les colonnes de cette table. Cette recherche coûtera un peu de temps – pas beaucoup en une seule requête – mais elle s’accumule au fil du temps

  • Si vous n’avez besoin que des 2/3 des colonnes, vous sélectionnez 1/3 de données en trop qui doivent être extraites du disque et envoyées sur le réseau

  • Si vous commencez à vous fier à certains aspects des données, par exemple l’ordre des colonnes renvoyées, vous risquez de connaître une mauvaise surprise une fois la table réorganisée et les nouvelles colonnes ajoutées (ou celles qui sont déjà supprimées).

  • Dans SQL Server (pas sûr des autres bases de données), si vous avez besoin d’un sous-ensemble de colonnes, il est toujours possible qu’un index non clusterisé couvre cette requête (contient toutes les colonnes nécessaires). Avec un SELECT * , vous abandonnez cette possibilité dès le départ. Dans ce cas particulier, les données seraient récupérées à partir des pages d’index (si celles-ci contiennent toutes les colonnes nécessaires) et, par conséquent, les E / S de disque et les surcharges de mémoire seraient beaucoup moins importants qu’une requête SELECT *....

Oui, il faut commencer par taper un peu plus (des outils comme SQL Prompt pour SQL Server vous y aideront même) – mais c’est vraiment un cas où il y a une règle sans aucune exception: n’utilisez jamais SELECT * dans votre code de production. DÉJÀ.

Vous devez toujours select uniquement les colonnes dont vous avez réellement besoin. Il n’est jamais moins efficace de sélectionner moins au lieu de plus, et vous rencontrez également moins d’effets secondaires inattendus – comme accéder à vos colonnes de résultats côté client par index, puis avoir ces index incorrects en ajoutant une nouvelle colonne à la table.

[edit]: Vouloir accéder. Cerveau stupide se réveillant encore.

À moins de stocker de gros blobs, les performances ne sont pas une préoccupation. La grande raison de ne pas utiliser SELECT * est que si vous utilisez des lignes renvoyées comme tuples, les colonnes reviennent dans l’ordre spécifié par le schéma et si cela change, vous devrez corriger tout votre code.

D’un autre côté, si vous utilisez un access de type dictionnaire, l’ordre dans lequel les colonnes reviennent n’a pas d’importance, car vous y accédez toujours par nom.

Cela me fait immédiatement penser à une table que j’utilisais et qui contenait une colonne de type blob ; Il contenait généralement une image JPEG, d’une taille de quelques Mb .

Inutile de dire que je n’ai pas SELECT cette colonne à moins que j’en avais vraiment besoin. Le fait que ces données circulent, en particulier lorsque j’ai sélectionné plusieurs lignes, n’était qu’un problème.

Cependant, je dois admettre que je demande généralement toutes les colonnes d’une table.

Au cours d’une sélection SQL, la firebase database se référera toujours aux métadonnées de la table, qu’il s’agisse de SELECT * pour SELECT a, b, c … Pourquoi? C’est là que se trouvent les informations sur la structure et la disposition de la table sur le système.

Il doit lire ces informations pour deux raisons. Un, pour simplement comstackr l’instruction. Il faut s’assurer que vous spécifiez une table existante au minimum. En outre, la structure de la firebase database peut avoir changé depuis la dernière exécution d’une instruction.

Maintenant, évidemment, les métadonnées de la firebase database sont mises en cache dans le système, mais le traitement doit encore être effectué.

Ensuite, les métadonnées sont utilisées pour générer le plan de requête. Cela se produit chaque fois qu’une déclaration est également compilée. Encore une fois, cela fonctionne contre les métadonnées en cache, mais c’est toujours fait.

Le seul moment où ce traitement n’est pas effectué est lorsque la firebase database utilise une requête pré-compilée ou a mis en cache une requête précédente. C’est l’argument de l’utilisation des parameters de liaison plutôt que du SQL littéral. “SELECT * FROM TABLE WHERE key = 1” est une requête différente de “SELECT * FROM TABLE WHERE key =?” et le “1” est lié à l’appel.

Les bases de données reposent fortement sur la mise en cache des pages pour leur travail. Beaucoup de bases de données modernes sont assez petites pour tenir complètement en mémoire (ou, devrais-je dire, la mémoire moderne est assez grande pour contenir de nombreux DB). Ensuite, les coûts d’E / S principaux à l’arrière-plan sont enregistrés et les vidages de page.

Cependant, si vous frappez toujours le disque pour votre firebase database, une optimisation primaire effectuée par de nombreux systèmes consiste à utiliser les données des index plutôt que les tables elles-mêmes.

Si tu as:

 CREATE TABLE customer ( id INTEGER NOT NULL PRIMARY KEY, name VARCHAR(150) NOT NULL, city VARCHAR(30), state VARCHAR(30), zip VARCHAR(10)); CREATE INDEX k1_customer ON customer(id, name); 

Ensuite, si vous faites “SELECT id, nom FROM customer WHERE id = 1”, il est très probable que votre firebase database extraira ces données de l’index, plutôt que des tables.

Pourquoi? Il utilisera probablement l’index pour satisfaire la requête (par rapport à une parsing de table), et même si «name» n’est pas utilisé dans la clause where, cet index sera toujours la meilleure option pour la requête.

Maintenant, la firebase database a toutes les données nécessaires pour satisfaire la requête, il n’y a donc aucune raison de toucher les pages de la table elles-mêmes. L’utilisation de l’index entraîne moins de trafic disque car la densité de lignes de l’index est supérieure à celle de la table en général.

Ceci est une explication manuelle d’une technique d’optimisation spécifique utilisée par certaines bases de données. Beaucoup ont plusieurs techniques d’optimisation et de réglage.

Au final, SELECT * est utile pour les requêtes dynamics que vous devez taper à la main, je ne l’utiliserai jamais pour du “vrai code”. L’identification des colonnes individuelles fournit au DB plus d’informations qu’il peut utiliser pour optimiser la requête et vous offre un meilleur contrôle de votre code contre les modifications de schéma, etc.

Je pense qu’il n’y a pas de réponse exacte à votre question, car vous réfléchissez à la performance et à la facilité de maintenance de vos applications. Select column est plus performant que select * , mais si vous développez un système d’objects orienté, alors vous aimerez utiliser object.properties et vous aurez besoin de propriétés dans n’importe quelle partie des applications, vous aurez besoin d’écrire plus de méthodes pour obtenir des propriétés. situations spéciales si vous n’utilisez pas select * et remplissez toutes les propriétés. Vos applications doivent avoir de bonnes performances en utilisant select * et dans certains cas, vous devrez utiliser select column pour améliorer les performances. Ensuite, vous aurez le meilleur de deux mondes, la possibilité d’écrire et de gérer des applications et des performances lorsque vous avez besoin de performances.

La réponse acceptée ici est fausse. Je suis tombé sur cela quand une autre question a été fermée en double (alors que j’écrivais encore ma réponse – grr – d’où le SQL ci-dessous fait référence à l’autre question).

Vous devez toujours utiliser l’atsortingbut SELECT, l’atsortingbut …. NOT SELECT *

C’est principalement pour les problèmes de performance.

SELECT nom FROM users WHERE name = ‘John’;

N’est pas un exemple très utile. Considérez plutôt:

 SELECT telephone FROM users WHERE name='John'; 

S’il existe un index sur (nom, téléphone), la requête peut être résolue sans avoir à rechercher les valeurs pertinentes dans la table – il existe un index de couverture .

De plus, supposons que la table ait un BLOB contenant une image de l’utilisateur et un CV téléchargé, et une feuille de calcul utilisant SELECT * ramènera toutes ces informations dans les tampons du SGBD (en forçant d’autres informations utiles du cache). Ensuite, tout sera envoyé au client en utilisant le temps passé sur le réseau et la mémoire sur le client pour les données redondantes.

Cela peut également entraîner des problèmes fonctionnels si le client récupère les données sous la forme d’un tableau énuméré (tel que mysql_fetch_array ($ x, MYSQL_NUM) de PHP). Peut-être que lorsque le code a été écrit “téléphone” était la troisième colonne à retourner par SELECT *, mais alors quelqu’un arrive et décide d’append une adresse e-mail à la table, positionnée avant “telephone”. Le champ souhaité est maintenant déplacé vers la 4ème colonne.

Il y a des raisons de faire les choses de toute façon. J’utilise beaucoup SELECT * sur PostgreSQL car il y a beaucoup de choses que vous pouvez faire avec SELECT * dans PostgreSQL que vous ne pouvez pas faire avec une liste de colonnes explicite, en particulier dans les procédures stockées. De même, dans Informix, SELECT * sur une arborescence de tables héritée peut vous donner des lignes irrégulières alors qu’une liste de colonnes explicite ne peut pas l’être car des colonnes supplémentaires dans les tables enfants sont également renvoyées.

La principale raison pour laquelle je le fais dans PostgreSQL ™ est que je m’assure qu’un type bien formé est spécifique à une table. Cela me permet de prendre les résultats et de les utiliser comme type de table dans PostgreSQL. Cela permet également beaucoup plus d’options dans la requête qu’une liste de colonnes rigide.

D’un autre côté, une liste de colonnes rigide vous permet de vérifier au niveau de l’application que les schémas de firebase database n’ont pas changé de certaines manières et cela peut être utile. (Je fais de telles vérifications à un autre niveau.)

En ce qui concerne les performances, j’ai tendance à utiliser des vues et des procédures stockées renvoyant des types (puis une liste de colonnes dans la procédure stockée). Cela me permet de contrôler quels types sont retournés.

Mais gardez à l’esprit que j’utilise SELECT * généralement contre une couche d’abstraction plutôt que des tables de base.

Référence tirée de cet article:

Sans SELECT *: Lorsque vous utilisez «SELECT *» à ce moment-là, vous sélectionnez plus de colonnes dans la firebase database et certaines de ces colonnes peuvent ne pas être utilisées par votre application. Cela créera des coûts et des charges supplémentaires sur le système de firebase database et davantage de données voyageront sur le réseau.

Avec SELECT *: Si vous avez des exigences spéciales et créez un environnement dynamic lorsque vous ajoutez ou supprimez une colonne, vous gérez automatiquement le code de l’application. Dans ce cas particulier, vous n’avez pas besoin de modifier le code de l’application et de la firebase database, ce qui affecte automatiquement l’environnement de production. Dans ce cas, vous pouvez utiliser “SELECT *”.

Juste pour append une nuance à la discussion que je ne vois pas ici: En termes d’E / S, si vous utilisez une firebase database avec un stockage en colonnes, vous pouvez faire BEAUCOUP moins d’E / S si vous ne demandez que certaines données. colonnes. Au fur et à mesure que nous passons aux SSD, les avantages peuvent être un peu plus petits que le stockage orienté ligne mais il y a a) seulement la lecture des blocs contenant des colonnes qui vous intéressent b) la compression, ce qui réduit généralement la taille des données sur le disque volume de données lues à partir du disque.

Si vous n’êtes pas familier avec le stockage en colonnes, une implémentation pour Postgres provient de Citus Data, une autre est Greenplum, une autre Paraccel, une autre en gros (Amazon Redshift). Pour MySQL, il y a Infobright, l’infiniDB maintenant disparu. Les autres offres commerciales incluent Vertica de HP, Sybase IQ, Teradata …

 select * from table1 INTERSECT select * from table2 

égal

 select distinct t1 from table1 where Exists (select t2 from table2 where table1.t1 = t2 )