I/
Les leviers à notre
disposition
les préconisations matérielles d'IBM pour
les bases décisionnelles, sont les suivantes :
CQE effectue un calcul simple : "taille du pool/ niveau d'activité" = mémoire maxi par job.
Si votre requête s'exécute seule dans un pool (ce
qui est
conseillé) , descendez le niveau d'activité
à 1.
»Pour travailler dans un Pool dédié :
» En même temps, utilisez l'expert cache qui est
toujours une bonne solution pour les accès base de
données, dans des pools mémoire de plus de 100 Mo
(on garde en mémoire les tables les plus
utilisées).
SQE,
lui
divise la taille du pool par le nombre moyen
de travaux
(expert cache obligatoire, pour faire la
moyenne)
ATTENTION, Si vous faites des tests, le deuxième test ira toujours plus vite que le premier, du fait que les données sont (partiellement ?) restées en mémoire, ce qui peut fausser vos mesures.
Placez vous alors Obligatoirement
dans un pool ou vous êtes seul, et lancez entre deux
requêtes :
CLRPOOL POOL(*SHRPOOL1)
-> Pour garder les données complètement en mémoire pour pouvez utiliser la commande SETOBJACC ou bien la nouvelle fonctionnalité de la version 7 :
- Le pool mémoire utilisé est celui indiqué par MEMORY_POOL_PREFERENCE du fichier QAQQINI, qui doit être à *CALC :
- Le fichier est monté en mémoire "à la demande" (lors de la première requête) en mode asynchrone et en parallèle
(contrairement à SETOBJACC qui n'utilisait qu'un seul thread)
- La conservation complète du fichier n'est pas garantie, mais si vous avez de la mémoire elle est fort probable
Pour visualiser la mémoire consommée par SQL, Regardez SYSTMPSTG (Bucket *DATABASE...)
Ce paramètre est renseignable sur les commandes STRSQL , RUNSQLSTM
- *NO la copie des données n'est pas admises (pour des
besoins
de temps réel)
- *YES la copie des données est admise, elle n'a lieu que quand il est impossible de faire autrement
- *OPTIMIZE la copie des
données est admise, elle aura lieu
à chaque fois que cela améliorera les temps de
réponses
(particulièrement le hachage pour les jointures et les index
bitmap)
c'est cette dernière valeur qu'il faut
privilégier (elle
est par défaut via ODBC./JDBC).
Vous pouvez influencer l'optimiseur de requêtes en indiquant le nombre de lignes à traiter en même temps :
Si vous indiquez une petite valeur, l'optimiseur cherche à
rendre un résultat le plus rapide possible, vous le forcer
à utiliser des index, même si le temps global doit
en
pâtir.
C'est une solution interactive (STRSQL considère, sans
indication de votre part, une optimisation pour 3% des lignes du
fichier)
Si vous indiquez une GRANDE
valeur (FOR ALL ROWS est admis depuis
V4R30) l'optimiseur privilégie le temps global de
traitement.
Vous favoriserez les copies temporaires, les tris, le hachage s'ils
sont plus efficaces)
C'est une solution purement orientée batch et gros volumes.
(INSERT into …SELECT … FORM …, est
toujours traité pour un
nombre maxi de lignes)
WRKSYSSTS (gestion de la mémoire)
ATTENTION, tous ces écrans vous offrent des
moyennes, il faut
visualiser des données qui ont au moins 2 minutes .
la documentation V5R40 indique comme base de calcul rapide, par pool (ligne) :
c*p, où
c est le pourcentage de CPU utilisé
p est le nombre de processeurs de la partitionpar exemple
1 processeur à 36 % = 36 de taux de pagination maxi
1,8 processeur (LPAR) utilisé à 80% = 144
C'est aussi cet écran (par F11) qui permet de fixer l'expert cache.
WRKDSKSTS (gestion des disques)
cet écran montre le taux d'occupation des disques
(l'idéal est un taux de 75 % au maximum)
ainsi que l'activité des bras (% util).Une
activité au
delà de 50% indique des disques très
occupés.
si la répartition n'est pas linéaire (achat de
nouveaux
disques, par exemple), passez la commande STRASPBAL
TYPE(*CAPACITY)
D'abord un petit, "truc", mettez le paramètre QRYTIMLMT à 0 par la commande CHGQRYA :
toutes vos requêtes seront alors refusées (CPA4259) , l'optimiseur vous indiquant le temps qu'il a prévu.1/ En interactif, passez la commande STRDBG avant de lancer SQL en mode 5250 ,
vous verrez alors après chaque requête des messages CPI43xx ainsi que SQL79xx dans l'historique indiquant les choix de l'optimiseur lors de la création du plan d'accès
2/
pour un programme, vous pouvez voir le plan d'accès par la
commande PRTSQLINF
vous verrez alors, dans un
spool portant le nom du pgm, pour chaque requête des messages
SQL40xx
3/ Pour les Batch, utilisez le Moniteur base de données :
dans une session 5250, lancez la commande STRDBMON
rappel, utilisez les paramètres suivants
- RUNTHLD : seuil en secondes, de temps d'exécution
- STGTHLD : seuil en Mo de mémoire utilisée
- FTRFILE : filtrage du moniteur sur un nom de fichier
- FTRUSER : filtrage du moniteur sur un profil utilisateur
- FTRINTNETA : filtrage du moniteur sur une adresse IP cliente
- FTRQRYGOVR : filtrage du moniteur sur l'annulation de la demande pour dépassement de critère donné par CHGQRYA
et le paramètre FTRCLTPGM de STRDBMON admet le filtre RUNQRY et STRQMQRY
SI46394 (7.1) place, en cas de "embeded SQL", dans :
-> pour analyser ensuite le résultat, IBM propose la création de vues voir https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_71/rzajq/lofdds.htm
ou mieux, via ACS (voir ci-dessous) :
Utilisez "Performance Center"
Les
outils graphiques
Vous pouvez :
sauvegarder
et relire un script SQL
lancer
tout ou partie du script
demander
l'inclusion des messages Debug et voir l'historique du travail sur
le serveur
une option ALLOW SAVE RESULT, permet la sauvegarde des
enregistrements extraits:
ensuite, avec un clic droit sur les lignes affichées :
Les formats admis, sont :
Plusieurs paramètrages de la connexion (JDBC) peuvent être mémorisés
Vous choisissez ensuite comme ceci :
Vous avez accès aux travaux et à la dernière requête SQL pour chacun d'eux (Affichage/SQL details for a Job)
Enfin, la(les) requêtes(s) peuvent être
sauvegardée(s) (uniquement en local)
cliquez sur moniteur de Base de données / nouveau ...
remarquez :
Choix des travaux
et récapitulatif final.
Quand la trace est terminée (l'arrêt est à votre charge), choisissez une vue (les données à afficher)
Avec un classement par catégorie
![]()
![]()
IBM fournit des requêtes
d'exemple afin d'obtenir des statistiques globales à
l'adresse https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_71/rzajq/rzajqmon4.htm
Résultat
![]()
Avec accès à Visual Explain et à l'instruction dans le gestionnaire de scripts
![]()
Vous pouvez aussi utiliser IBM Navigator for I (Performances/Etude des données) :
Mais surtout, nous avons maintenant des statistiques d'Entrée/Sortie globales (sous PDI)
Choisissez la bibliothèque et la collecte (ou laissez "la plus récente")
Entrée/sortie base de donnée physiques, vue détaillée
Par travail :
Par sous-système
Par type de serveur
Longuest Run
Job History
User History
Work with SQL Statement, place la requête dans le gestionnaire de scripts, vu plus haut.
Le jeu d'instructions actuellement en cache pouvant être
sauvegardé sous forme d'image (snapshot).
(sinon, il y a mise à blanc à l'IPL)
•Depuis Performance Center
![]()
•Par appel à la procédure cataloguée QSYS2/DUMP_PLAN_CACHE(bibliothèque, nom_de_sauvegarde)
- Quand le cache est plein il est automatiquement épuré, il est possible de placer un moniteur sur cet événement afin de le sauvegarder en fichier avant (Event Monitor)
Tout en gardant la possibilité de choisir les instructions sauvegardées (comme un moniteur)
![]()
Cette sauvegarde peut ensuite, être réutilisée pour une comparaison :
il n'est pas possible de comparer un jeu d'instructions venant du cache et un moniteur
Pour définir ou voir les statistiques, Utilisez la nouvelle (1.1.7) option Schémas
Include permet de choisir les bibliothèques à afficher
Toutes les listes peuvent être sauvegardées
![]()
Vous avez le choix des colonnes à l'affichage
• Liste des tables
ET depuis la 1.1.7.1, l possibilité de filtrer![]()
Sur une table, option "Satistic Data"
![]()
Vous montre les statistiques réalisées
![]()
- New permet de demander une nouvelle statistique sur une colonne
- Details permet de voir une statistique existante
![]()
- cardinalité (nombre de valeurs différentes)
- nombre de valeurs nulles
- nombre de lignes
- Histogramme (répartition des plages de valeur, avec le nombre de ligne)
- Top 50
Statistiques
d'utilisation des index
ACS, montre les index liés à une
table (clic droit sur la table)
Ce dernier vous affiche des informations, nouvelles en
V5R40 concernant l'utilisation des index
En effet, la date de dernière utilisation de l'objet fichier logique,
n'est pas significative dans le cas d'une requête SQL,
où c'est l'optimiseur qui décide de l'utilisation ou non
de l'index (utilisation non explicite).
Vous avez ici, 4 colonnes remarquables
-> clé basée sur une expression
-> type d'index
Avec la V5R40, lors de la création des plans d'accès,
le système
note les index qui lui paraissent manquant dans QSYS2/SYSIXADV.
Le contenu de ce fichier est affiché par cette option "Assistant
de gestion des index" d'iSeries Navigator
Depuis la V5R4, le système créé lui
même sous forme d'index temporaires,
les index qu'il juge nécessaires . (fonction MTI soit Maintained
Temporary Indexes), ces index disparaissent à l'IPL.
vous pourrez le constater, toujours en demandant l'assistant
de gestion d'index
(sur la machine , sur un nom de schéma, sur un nom de table).
la nouveauté se trouve tout à droite de cette fenêtre
- Affichage de l'instruction SQL(Show SQL) montre l'ordre CREATE INDEX
- ainsi que l'accès direct aux instructions qui ont provoqué cette suggestion (dans le cache, voir ci-dessous)
- l'assistant affiche aussi le nombre de fois ou un index a été suggéré et, s'il a été créé automatiquement (MTI), le nombre de fois où il a été utilisé
Ce compteur peut-être réinitialisé pour la table, par le menu contextuel suivant :
voici donc, maintenant la structure de la table SYSIXADV (V7)
nom de la colonne (zone) nom système Type de donnée Description TABLE_NAME TBNAME VARCHAR(258) Table sur laquelle l'index est suggéré TABLE_SCHEMA DBNAME CHAR(128) Schéma de la table SYSTEM_TABLE_NAME SYS_TNAME CHAR(10) nom système (court) de la table PARTITION_NAME TBMEMBER CHAR(10) Partition KEY_COLUMNS_ADVISED KEYSADV VARCHAR(16000) nom des clés suggérées LEADING_COLUMN_KEYS LEADKEYS VARCHAR(16000) clé principale, dont le critère de tri (croissant/décroissant) n'importe pas. INDEX_TYPE INDEX_TYPE CHAR(14) type d'index (normal ou EVI) LAST_ADVISED LASTADV TIMESTAMP date/heure de suggestion TIMES_ADVISED TIMESADV BIGINT nombre de fois la suggestion a été faite ESTIMATED_CREATION_TIME ESTTIME INT nombre de secondes(estimées) pour la création REASON_ADVISED REASON CHAR(2) Code raison (Sélection / tri ou groupage / les deux) LOGICAL_PAGE_SIZE PAGESIZE INT taille des pages recommandée MOST_EXPENSIVE_QUERY QUERYCOST INT temps d'exécution le plus long AVERAGE_QUERY_ESTIMATE QUERYEST INT temps d'exécution moyen TABLE_SIZE TABLE_SIZE BIGINT nombre de lignes dans la table (lors de la suggestion) NLSS_TABLE_NAME NLSSNAME CHAR(10) Séquence de tri à utiliser NLSS_TABLE_SCHEMA NLSSDBNAME CHAR(10) Bibliothèque de la séquence de tri MTI_USED MTIUSED BIGINT Nombre de fois ou cet MTI a été utilisé
(le système n'utilise plus un MTI, dès qu'un index permanent existe)MTI_CREATED MTICREATED INT Nombre de fois ou cet MTI a été créé
(rappel un index MTI disparaît à l'IPL)LAST_MTI_USED LASTMTIUSE TIMESTAMP Date/heure de dernière utilisation de cet index MTI. AVERAGE_QUERY_ESTIMATE _MICRO QRYMICRO BIGINT temps moyen d'exécution de la requête à l'origine de cette suggestion EVI_DISTINCT_VALUES EVIVALS INTEGER Nombre de valeurs distinctes pour création index EVI INCLUDE_COLUMNS INCLCOL CLOB(10000) INCLUDE pour création index EVI FIRST_ADVISED FIRSTADV TIMESTAMP Première suggestion SYSTEM_TABLE_SCHEMA SYS_DNAME CHAR(10) Nom système de la bibliothèque MTI_USED_FOR_STATS + MTISTATS BIGINT Nbr de fois, Index MTI utilisé pour des statistiques LAST_MTI_USED_FOR_STATS * LASTMTISTA TIMESTAMP dernière utilisation Index MTI pour des statistiques DEPENDENT_ADVICE_COUNT ** DEPCNT CHAR(10) Nombre de dépendances d'index (traitement de OR) * SF99701, level 14 : les index MTI peuvent être utilisés pour collecter des performances
** SF99701, level 23 : les index proposés sont liés et utilisables par la même requête contenant des OR
Exemple :
select * from vins where vin_cepage1 = 'Cabernet' or vin_cepage2 = 'Cabernet' or vin_cepage3 = 'Cabernet' Contenu de SYSIXADV
INDEX_TYPE DEPENDENT_ADVICE_COUNT KEY_COLUMNS_ADVISED
----------- --------------------- -------------------
RADIX 1 VIN_CEPAGE1
RADIX 1 VIN_CEPAGE3
RADIX 1 VIN_CEPAGE2
LA PTF SF99701, level 12 (SF99601 level 21 en V6) propose deux procédures cataloguées
Vous pouvez retrouver les sources de ces procédures via System i Navigator ou ACS (elles sont livrées "tel que") et les personnaliser.
4/
Visual Explain
Vous pouvez maintenant obtenir une Explication graphique du détail d'une requête SQL avec Visual Explain :
Visual Explain peut être
lancé et réactualisé,
pendant l'exécution, les informations ayant
bougé sont surlignées.
Visual
Explain vous affiche alors le détail des
différentes phases de la requête :
A partir de cette requête
•Scannage de table et/ou utilisation d'un index
• phase de jointure
ici en utilisant des index pour la jointure
et avec agrégation (pour count(*) )![]()
Le résultat étant stocké dans une liste temporaire
ici, le résultat final indiquant le moteur utilisé
ici la phase jointure
Les messages de l'optimiseur (précisant la jointure)
étant affichés dans cet onglet![]()
depuis la 6.1, SQE possède un module d'auto-apprentissage, qui agit aujourd'hui dans 2 cas :
Vous pouvez aussi lancer Visual Explain sur le résultat d'un moniteur de performance base de données.
· Les informations affichées par Visual Explain
Chaque
icône représente une action :
Icône | STRDBG | PRTSQLINF | Commentaires |
![]() Table Scan |
CPI4329 | SQL4010 | Utilisé pour retourner un grand nombre de lignes |
![]() Table Probe |
Accès
direct à une ligne par son n° de rang (la connaissance du n° de rang peut venir d'une lecture d'index) |
||
![]() Index Scan |
CPI4328 | SQL4008 |
utilisé pour
retourner un petit
nombre de lignes, si l'index correspond au critère de tri ET à une
sélection,
par exemple. |
![]() Index Probe |
CPI4338 | SQL4032 |
utilisé pour
retourner un petit
nombre de lignes, l'index permettant de réaliser la
sélection la plus importante (primary key, par exemple) |
![]() EVI Probe |
CPI4328 | SQL4008 SQL4011 |
utilisé éventuellement avec
d'autres pour créer un bitmap, entraîne ensuite un
accès direct sur la table (table
probe) |
Icône | STRDBG | PRTSQLINF | Commentaires |
![]() Hash Scan |
CPI4329 | SQL4010 SQL4029 |
Utilisé principalement pour la
gestion du GROUP
BY |
![]() HASH Probe |
CPI4327 | SQL4007 SQL4011 |
Utilisé principalement pour la jointure |
![]() Liste triée (Scan) |
CPI4328 CPI4325 |
SQL4008 SQL4002 |
Utilisé pour Order BY et l'option
DISTINCT |
![]() Liste triée (Probe) |
CPI4327 | SQL4007 SQL4010 |
Utilisé pour une jointure avec un autre
critère
que l'égalité |
![]() Liste simple (Scan) |
CPI4325 CPI4327 |
SQL4007 SQL4010 |
Utilisé pour préparer une
utilisation
parallèle (SMP) |
![]() Liste numérotée (Scan) |
Utilisé avec des index multiples pour
favoriser
ensuite le groupage des I/O disque. (récupération
physique des
lignes par paquet) |
||
![]() Liste numérotée (Accès direct) |
CPI4338 | SQL4032 | technique bitmap pour combiner plusieurs index et
limiter
ensuite l'accès direct aux lignes de la table |
![]() Bitmap Scan |
CPI4338 | SQL4010 SQL4032 |
technique pour combiner plusieurs index en un index
bitmap. Un index bitmap est un nuage de point ou chaque position représente l'adresse, un liste numérotée contient les adresses (N° de rang) |
![]() Accès direct Bitmap |
CPI4338 | SQL4011 SQL4032 |
technique bitmap pour combiner plusieurs index et
limiter
ensuite l'accès direct aux lignes de la table |
![]() Index Scan |
CPI4321 | SQL4009 |
Utilisation d'un
index temporaire
pour tri ou groupage (MTI) |
![]() Index Probe |
CPI4321 | SQL4009 |
Utilisation d'un index temporaire, probablement pour jointure |
![]() |
CPI4330 | SQL4030 | Objet temporaire utilisé lors des opérations de parallélisme (SMP) |
Enfin, l'icône vous
donnera des informations globales (temps,
nombre de lignes résultat , ...)
Nouveaux en V5R40
![]() EVi table Scan, preload |
CPI4328 | SQL4008 |
utiliser pour retrouver les entrées à partir uniquement de la table des symboles d'un index EVI |
![]() QUEUE/DEQUEUE |
(pas de message) | (pas de message) | QUEUE, Objet temporaire pour mémoriser des données durant une requête récursive |
Nouveaux en V6R10
![]() temporary distinct Sorted list Scan |
(pas de message) | (pas de message) | Liste triée de valeurs distinctes, utilisée pour GROUP BY ROLLUP |
![]() temporary value List Scan |
Arrival sequence was used for file *VALUES |
SQL4010 | Liste de valeurs temporaires, utilisée avec VALUES( ) |
Nouveaux en V7 (les index EVI peuvent maintenant être utilisés en lecture pour GROUP BY et DISTINCT)
![]() EVI Table SCAN, preload |
SQL4008 | Lecture d'un Index EVI avec INCLUDE pour fonction d'agrégation (GROUP BY) | |
![]() EVI Table Probe, Preload |
SQL4008 | Lecture d'un Index EVI avec INCLUDE pour fonction d'agrégation (GROUP BY et WHERE) | |
![]() UNNEST ARRAY |
SQL4010 | Utilisation de la fonction UNNEST d'un tableau SQL (ARRAY) dans une procédure | |
![]() EVI Only Access |
Utilisation de deux index EVI, l'un pour la sélection, l'autre pour les colonnes à afficher (la table n'est pas lue, voir ce cours) |
Visual Explain sait pleinement tirer profit des différentes évolutions, comme la collecte de statistiques.
le Menu Option propose
Un certain nombre d'actions, dont un
outil de conseil
ou
la création d'index
Le menu VUE, peut mettre en évidence
les
index recommandés
ce qui s'affiche :
SI Visual Explain utilise une table matérialisée (MQT)
vous verrez son nom (et CPI4329 si le debug est actif)
les étapes
les plus coûteuses
• Vous retrouverez ces informations depuis un moniteur
de fait quand on lance Visual Explain
Quelques recommandations
|