> Tech > L’accès direct par clé

L’accès direct par clé

Tech - Par Renaud ROSSET - Publié le 24 juin 2010
email

Le dernier groupe de tests consistait à  accéder à  des enregistrements par clé primaire, en utilisant une suite de valeurs de clé générées dans un ordre pseudo-aléatoire. (L'ordre des clés de test était différent de celui dans lequel elles avaient été générées à  l'origine et de leur ordre dans le

fichier.) Le programme de test RPG
a utilisé une opération Chain et les programmes de test SQL ont utilisé soit un
Fetch monoligne soit une instruction Select Into. Pour les tests de Fetch, le
curseur de la figure 9 a été ouvert et fermé à  chaque Fetch. Notons que SQL repositionne
simplement le pointeur du fichier pour cette suite d’opérations sans ouvrir et
fermer l’ODP sous-jacent à  chaque itération.

Comme avec l’accès séquentiel, j’ai démarré mon investigation en utilisant une
commande SetObjAcc avec Pool(*Job) pour analyser séparément les performances du
traitement en mémoire et celle du transfert de disque en mémoire.

Dans ces tests, j’ai extrait 100.000 enregistrements. Comme prévu, l’accès direct
est nettement plus lent que l’accès séquentiel (figure 2) pour RPG et SQL, et
RPG demande beaucoup moins de traitement en mémoire que SQL pour présenter les
données au programme d’application.

Pour l’accès direct, la séquence d’extraction des enregistrements ne suit aucun
profil défini, et donc il est peu intéressant de copier des blocs d’enregistrements
dans la mémoire-tampon de l’application. Par conséquent, il est inutile de définir
SeqOnly(*Yes) ou d’utiliser un Fetch multiligne pour ce type d’accès. On pourrait
aussi penser qu’il n’y pas d’intérêt à  avoir une taille de transfert plus grande
qu’un seul enregistrement, mais ce n’est pas ce que révèle le benchmark.

La figure 11 illustre l’amélioration des performances pour RPG et SQL lorsque
davantage d’enregistrements sont extraits. On voit également que la taille de
transfert augmente généralement. Au fur et à  mesure que davantage d’enregistrements
sont extraits, on constate deux phénomènes. Tout d’abord, le processus pseudo-aléatoire
commence à  générer de plus en plus de valeurs de clés répétitives au fil de la
génération. Pour 100.000 clés générées, environ 20.000 sont des répétitions, et
tant qu’un enregistrement reste en mémoire, aucun transfert n’est requis pour
les opérations Chain qui extraient une clé précédemment extraite.

De plus, au fur et à  mesure de l’extraction des enregistrements, la probabilité
d’un enregistrement se trouvant dans un bloc transféré précédemment augmente,
même pour les clés ne faisant l’objet que d’un accès. Comme nous l’avons vu avec
l’accès par clé séquentiel (qui extrayait aussi un grand pourcentage des enregistrements
du fichier), lorsque les enregistrements restent en mémoire, une grande taille
de transfert peut améliorer les performances. Mais, nous verrons bientôt que seul
le RPG semble exploiter cet avantage pour l’accès par clé direct.

La figure 11 donne les résultats des tests quand aucune commande OvrDbf n’a été
utilisée. La spécification *Calc pour les pools de mémoire partagée a provoqué
l’augmentation de la taille de transfert pour les tests extrayant un grand nombre
d’enregistrements. Les performances du RPG augmentent beaucoup plus rapidement
lorsque davantage d’enregistrements sont extraits. La raison en est que le RPG
possède un avantage de quatre à  un en traitement en mémoire (figure 10), ce qui
le favorise lorsque de moins en moins de transferts de disques sont nécessaires.

Pour cerner ce phénomène de plus près, j’ai effectué plusieurs séries de tests
en donnant des valeurs différentes à  NbrRcds. Pour RPG, j’ai effectué une série
qui a extrait 1.000 enregistrements et une autre qui en a extrait 10.000. Comme
on le voit figure 12a, quand un petit pourcentage (environ 1 % par exemple) des
enregistrements du fichier ont été extraits, la plus petite taille de transfert
a donné les meilleurs résultats. Mais quand environ 10 % des enregistrements du
fichier ont été extraits, l’augmentation de la taille de transfert jusqu’à  88
enregistrements a amélioré les performances. Au-delà  de ce point, les performances
se sont égalisées. Les deux colonnes contenant le nombre de demandes de transfert
expliquent pourquoi les deux séries ont donné des résultats différents. Quand
1.000 enregistrements seulement ont été extraits, on a trouvé peu d’enregistrements
dans un bloc de données déjà  transféré, indépendamment de la taille du transfert.
Ainsi, le coût supplémentaire entraîné par le transfert de davantage de données
a compensé l’économie d’un peu moins de transferts. Quand 10.000 enregistrements
ont été extraits, la réduction des demandes de transfert est devenue notable et
a largement compensé, et au-delà , les grandes tailles de transfert (jusqu’à  un
certain point, bien entendu).

La figure 12b présente une série de tests qui ont extrait 10.000 enregistrements
en utilisant un Fetch monoligne SQL. On constate une déficience apparente avec
SQL I/O quand on définit NbrRcds; même avec de plus grandes tailles de transfert,
le nombre de demandes de transfert n’a pas chuté autant qu’avec le test RPG comparable.
Je ne peux pas expliquer pourquoi le SQL Fetch ne trouve pas d’enregistrements
dans un bloc de données déjà  transféré, mais cette lacune diminue nettement les
performances.

Un autre problème apparent est apparu quand j’ai testé l’instruction SQL Select
Into pour l’accès par clé direct. Comme l’illustre la figure 12c, les performances
de Select Into sont plus ou moins comparables à  un SQL Fetch pour extraire 10.000
enregistrements ou moins. Mais, pour davantage d’extractions, Select Into est
loin d’améliorer les performances autant que Fetch (voir figure 11). Apparemment,
la taille de transfert n’est pas ajustée avec Select Into autant qu’elle l’est
avec Fetch, et donc il faut beaucoup plus de transferts pour Select Into pour
lire en mémoire l’ensemble d’enregistrements extraits.

Désormais vous connaissez les faits

En examinant ces résultats de benchmarks pour l’accès par clé direct RPG et SQL,
n’oubliez pas la discussion précédente concernant la contention de mémoire. En
particulier, de grandes tailles de transfert sont avantageuses lorsqu’on a beaucoup
de mémoire disponible et une contention basse, mais elles risquent de ne pas présenter
d’avantages, voire de constituer un handicap, quand la mémoire est étriquée ou
la contention lourde.

De plus, de grandes tailles de transfert peuvent être bénéfiques quand on extrait
un fort pourcentage des enregistrements d’un fichier, mais pénalisantes quand
le pourcentage est faible.

Pour en finir avec l’accès par clé direct, notons que le moyen le plus rapide
pour lire 100.000 enregistrements du fichier Master quand on dispose de suffisamment
de mémoire, consiste à  utiliser un SetObjAcc Pool(*Job) pour charger le fichier
en mémoire puis à  y accéder. Avec mes tests de benchmark, j’ai obtenu un débit
net de 75.950 pour RPG Chain, 22.800 pour SQL Fetch et 28.280 pour SQL Select
Into (tous ces débits sont nettement supérieurs aux meilleurs résultats des figures
12a à  12c). De petits fichiers  » lookup  » faisant l’objet d’accès fréquents peuvent
être d’excellents candidats pour le chargement en mémoire quand celle-ci est suffisante.

Téléchargez cette ressource

Préparer l’entreprise aux technologies interconnectées

Préparer l’entreprise aux technologies interconnectées

Avec la « quatrième révolution industrielle », les environnements hyperconnectés entraînent de nouveaux risques en matière de sécurité. Découvrez, dans ce guide Kaspersky, comment faire face à cette nouvelle ère de vulnérabilité.

Tech - Par Renaud ROSSET - Publié le 24 juin 2010