Question

Lorsque j'utilise JDBC, je rencontre souvent des constructions telles que

.
ResultSet rs = ps.executeQuery();
while (rs.next()) {
    int id = rs.getInt(1);
    // Some other actions
}

Je me suis demandé (et également aux auteurs de code) pourquoi ne pas utiliser les étiquettes pour récupérer les valeurs de colonne:

int id = rs.getInt("CUSTOMER_ID");

La meilleure explication que j'ai entendue concerne les performances. Mais en réalité, le traitement est-il extrêmement rapide? Je ne crois pas, même si je n'ai jamais effectué de mesures. Même si la récupération par étiquette serait un peu plus lente, néanmoins, elle offre une meilleure lisibilité et flexibilité, à mon avis.
Ainsi, quelqu'un pourrait-il m'expliquer de manière satisfaisante en évitant de récupérer les valeurs de colonne par index de colonne au lieu de libellé de colonne? Quels sont les avantages et les inconvénients des deux approches (peut-être concernant certains SGBD)?

Était-ce utile?

La solution

Vous devez utiliser les étiquettes de chaîne par défaut.

Avantages:

  • Indépendance de l'ordre des colonnes
  • Meilleure lisibilité / maintenabilité

Inconvénients:

  • Vous n'avez aucun contrôle sur les noms de colonne (accès via des procédures stockées)

Que préférez-vous?

ints?

  

int i = 1;
   customerId = resultSet.getInt (i ++);
   customerName = resultSet.getString (i ++);
   customerAddress = resultSet.getString (i ++);

ou des chaînes?

  

customerId = resultSet.getInt (" ID_client "");
   customerName = resultSet.getString ("quot_name");

   customerAddress = resultSet.getString ("quot_address_client");

Et si une nouvelle colonne était insérée à la position 1? Quel code préférez-vous? Ou si l’ordre des colonnes est modifié, quelle version de code devez-vous changer?

C'est pourquoi vous devez utiliser les étiquettes de chaîne par défaut.

Autres conseils

Attention: je vais devenir drastique ici, car cela me rend fou.

99% * du temps, c'est une micro-optimisation ridicule que les gens aient une vague idée de rendre les choses «meilleures». Cela ignore complètement le fait que, sauf si vous êtes dans une boucle extrêmement étroite et chargée sur des millions de résultats SQL tout le temps , ce qui est espérons-le rare, vous ne le remarquerez jamais. Pour tous ceux qui ne le font pas, le coût en temps nécessaire aux développeurs pour le maintien, la mise à jour et la correction des bogues dans l'indexation des colonnes est de loin supérieur au coût incrémentiel du matériel pour votre application dont la performance est infiniment pire.

Ne codez pas de telles optimisations dans. Code pour la personne qui la gère. Ensuite, observez, mesurez, analysez et optimisez. Observez à nouveau, mesurez à nouveau, analysez à nouveau et optimisez à nouveau.

L’optimisation est à peu près la dernière étape du développement, pas la première.

* La figure est composée.

La réponse a été acceptée, néanmoins, voici quelques informations supplémentaires et une expérience personnelle que je n'ai pas encore vu mettre en avant.

Utilisez des noms de colonnes (les constantes et non les littéraux sont préférables) en général et si possible. C’est à la fois plus clair, plus facile à gérer et les modifications futures risquent moins de casser le code.

Il existe toutefois une utilisation des index de colonnes. Dans certains cas, ils sont plus rapides, mais pas suffisamment pour que cela remplace les raisons ci-dessus pour les noms *. Celles-ci sont très utiles lors du développement d’outils et de méthodes générales traitant des ResultSet . Enfin, un index peut être requis car la colonne ne porte pas de nom (un agrégat non nommé, par exemple) ou s'il existe des noms en double, il n'existe donc aucun moyen simple de référencer les deux.

* Notez que j'ai écrit des pilotes JDBC et que j'ai regardé à l'intérieur de sources ouvertes et que ceux-ci utilisent en interne des index de colonnes pour référencer les colonnes de résultats. Dans tous les cas sur lesquels j'ai travaillé, le pilote interne mappe d'abord un nom de colonne sur un index. Ainsi, vous pouvez facilement voir que le nom de la colonne, dans tous ces cas, prendrait toujours plus de temps. Cela peut ne pas être vrai pour tous les pilotes cependant.

De la documentation Java:

  

L'interface ResultSet fournit des méthodes d'accesseur (getBoolean, getLong, etc.) permettant d'extraire les valeurs de colonne de la ligne en cours. Les valeurs peuvent être récupérées à l'aide du numéro d'index de la colonne ou du nom de la colonne. En général, l’utilisation de l’index de la colonne sera plus efficace. Les colonnes sont numérotées à partir de 1. Pour une portabilité maximale, les colonnes de l'ensemble de résultats de chaque ligne doivent être lues dans un ordre allant de gauche à droite, et chaque colonne ne doit être lue qu'une fois.

Bien sûr, chaque méthode (nommée ou indexée) a sa place. Je conviens que les colonnes nommées devraient être la valeur par défaut. Cependant, dans les cas où un grand nombre de boucles est requis et où l'instruction SELECT est définie et conservée dans la même section de code (ou classe), les index doivent être corrects - il est conseillé de répertorier les colonnes sélectionnées, et pas seulement. "SELECT * FROM ...", car tout changement de table annule le code.

Bien sûr, l’utilisation de noms de colonnes augmente la lisibilité et facilite la maintenance. Mais utiliser des noms de colonnes a un revers. Comme vous le savez, SQL autorise plusieurs noms de colonne portant le même nom, rien ne garantit que le nom de colonne que vous avez tapé dans la méthode getter de resultSet pointe réellement sur le nom de colonne auquel vous souhaitez accéder. En théorie, il est préférable d’utiliser des numéros d’indexation au lieu de noms de colonnes, mais cela réduit la lisibilité ...

Merci

Je ne pense pas que l’utilisation des étiquettes influe beaucoup sur les performances. Mais il existe une autre raison de ne pas utiliser String . Ou int s, d'ailleurs.

Pensez à utiliser des constantes. L'utilisation d'une constante int rend le code plus lisible, mais moins susceptible de comporter des erreurs.

En plus d'être plus lisible, la constante vous empêche également de faire des fautes de frappe dans les noms d'étiquette - le compilateur émettra une erreur si vous le faites. Et tout IDE digne de ce nom l’aura. Ce n'est pas le cas si vous utilisez String s ou ints .

J'ai effectué des analyses de performances sur ce sujet précis dans une base de données Oracle. Dans notre code, nous avons un ResultSet avec de nombreuses colonnes et un grand nombre de lignes. Sur les 20 secondes (!) Nécessaires à la requête pour exécuter la méthode oracle.jdbc.driver.ScrollableResultSet.findColumn (nom de chaîne) prend environ 4 secondes.

Évidemment, il y a quelque chose qui ne va pas dans la conception générale, mais utiliser des index au lieu des noms de colonnes prendrait probablement 4 secondes.

Vous pouvez avoir le meilleur des deux! La rapidité d'utilisation des index avec la maintenabilité et la sécurité de l'utilisation des noms de colonne.

Premièrement, à moins que vous ne fassiez une boucle dans un jeu de résultats, utilisez simplement des noms de colonnes.

  1. Définissez un ensemble de variables entières, une pour chaque colonne à laquelle vous aurez accès. Les noms des variables peuvent inclure le nom de la colonne: par ex. iLast_Name.

  2. Avant la boucle du jeu de résultats, parcourez les métadonnées de colonne et définissez la valeur de chaque variable entière sur l'index de colonne du nom de colonne correspondant. Si l'index de la colonne "Nom_du_nom" est égal à 3, définissez la valeur de "iLast_Name" sur 3.

  3. Dans la boucle du jeu de résultats, utilisez les noms de variable entiers des méthodes GET / SET. Le nom de la variable est un indice visuel pour le développeur / responsable en ce qui concerne le nom de la colonne à accéder mais la valeur correspond à l'index de la colonne et donnera les meilleures performances.

REMARQUE: le mappage initial (c'est-à-dire le mappage du nom de colonne en index) est effectué une seule fois avant la boucle et non pour chaque enregistrement et colonne de la boucle.

Le pilote JDBC prend soin de la recherche d'index de la colonne. Donc, si vous extrayez des valeurs par nom de colonne chaque fois que le pilote effectue une recherche (généralement dans une carte de hachage), vérifiez l'index correspondant pour le nom de la colonne.

Je suis d’accord avec les réponses précédentes pour affirmer que les performances ne nous obligent pas à choisir l’une ou l’autre des approches. Il serait bon de considérer plutôt les points suivants:

  • Lisibilité du code: pour chaque développeur qui lit vos étiquettes de code ont beaucoup plus de sens que les index.
  • Maintenance: pensez à la requête SQL et à la façon dont elle est maintenue. Ce qui est plus susceptible de se produire dans votre cas après la correction / amélioration / refactoring d’une requête SQL: changer l’ordre des colonnes extraites ou changer les noms des colonnes de résultats. Il me semble que la probabilité de changer l’ordre des colonnes extraites (à la suite de l’ajout / suppression de nouvelles colonnes dans le jeu de résultats) a plus de chances de se produire.
  • Encapsulation: malgré la manière que vous choisissez, essayez d’isoler le code où vous exécutez la requête SQL et analysez le jeu de résultats dans le même composant et informez uniquement ce composant des noms de colonne et de leur correspondance avec les index (si vous avez décidé de les utiliser).

L’utilisation de l’index est une tentative d’optimisation.

Le temps gagné par cette opération est gaspillé par les efforts supplémentaires que le développeur doit faire pour rechercher les données nécessaires pour vérifier si son code fonctionnera correctement après les modifications.

Je pense que c'est notre instinct intégré d'utiliser des chiffres à la place du texte.

Outre la recherche dans Map for labels, cela conduit également à une création supplémentaire de chaîne. Bien que cela se produise sur une pile, cela n'en coûtera pas moins un coût.

Tout dépend du choix individuel et jusqu'à la date du jour, je n'ai utilisé que des index: -)

Comme le signalent d’autres affiches, j’en resterais aux noms de colonnes, à moins que vous n’ayez une raison très forte de ne pas le faire. L'impact sur les performances est négligeable par rapport, par exemple, à l'optimisation des requêtes. Dans ce cas, la maintenance est beaucoup plus importante qu’une petite optimisation.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top