V7R20
SQE : Utilisation des Index avec sélection
- Sur les versions précédentes, SQE ne savait pas utiliser les index avec sélection d'enregistrement, d'ailleurs il y avait une option
(dans le fichier d'options QAQQINI) : IGNORE_DERIVED_INDEX
Le principe était le suivant, puisque SQE ne sait pas utiliser les index dit dérivés (avec Sélection/Omission)
- La donne change en 7.1, 7.2. Voici ce que dit la doc :
SQE supporte les logiques simples
- Sauf pour traitement OmniFInd
- Sauf logique sur un table partitionnée (multi-membres)
- Uniquement pour Select (pas Update, Insert, Delete)
- L'option IGNORE_DERIVED_INDEX est encore supportée
- elle engendre un traitement de la requête pas CQE
- EN 7.2 cette option n'est plus officiellement supportée (non documentée)
- SQE est utilisé dans tous les cas de figure, sauf :
- INSERT WITH VALUES
- INSERT d'une sous sélection
- Manipulation de tables avec Trigger à la lecture (ADDPFTRG)
- DB2 multi-systèmes (table partitionnée, éclatée sur plusieurs systèmes)
- API QQQQRY
- SQE (en 7.2) est utilisé même avec :
- QUERY
- OPNQRY
Pour ce dernier cas, cela améliore les performances, mais peut nécessiter un critère de tri explicite
Quelques tests
Tous les exemples qui viennent sont basés sur les fichiers log du serveur www.volubis.fr transformés en base de données
(base de 24 millions de lignes sur notre petit S814
)
- Regardons l'utilisation d'un Index (LF) dans la clause From d'un SELECT
Aux yeux de SQL, un LF représente deux choses :
- un format (comme une vue), particulièrement si le nom de format est différent
- un index (si des clés sont définies, on peut faire des logiques sans clé)
C'est bien SQE qui fait le JOB

les lignes ne sont pas triées (preuve que l'index dans le LF n'a pas été utilisé)

Sauf si vous ajoutez ORDER BY

A moins qu'il y ait une sélection et un autre index intéressant pour cette sélection, auquel cas on fera le tri ensuite, en mémoire
(SQE privilégie la diminution des I/O qui est souvent la phase la plus coûteuse)

- Regardons maintenant un logique avec Sélection/Omission

Le logique est lu pour respecter la sélection

D'ailleurs les statistiques d'utilisation sont mises à jour, dans tous les cas :
Avant
Utilisation implicite (ici pour réaliser le WHERE)
Après

Là aussi, sauf clause WHERE, plus restrictive (et un index pertinent)

Pourtant la sélection est respectée
- Enfin, même chose avec un Index SQL avec clause Where

Pas d'utilisation explicite (SQL refuse de lire des Index, uniquement des tables/PF et des vues)

Mais, utilisation implicite
- Pareil pour les index SQL utilisant des expressions en tant que clé

Utilisation implicite

- Les index EVI sont aussi utilisés implicitement pour la sélection d'enregistrement (c'est leur intérêt historique) particulièrement sur de gros volumes


Syntaxe SQL : CREATE ENCODED VECTOR INDEX ...
Rappel
- les index EVI ne sont utilisables que par SQL (pas en RPG/COBOL)
- les index EVI se cumulent parfaitement, en technique bitmap :
(quatre critères dans le WHERE, un index EVI par critère : SQL en fait un seul à partir des 4)
- les index EVI sont constitués de deux éléments
- Une table des symboles contenant :
- un code attribué à chaque valeur de clé
- des informations statistiques (nbr, position du premier record, position du dernier record ayant cette clé)
- Un vecteur
- attribuant à chaque rang, un des codes de la table des symboles vues plus haut.

Exemple avec un Select simple

SQL va chercher les lignes de rang 5 ,7 ,8 etc....
Sous Visual Explain
SI vous demandez count(*) l'accès à la table n'est même pas réalisé (l'index EVI suffit)

Depuis la version 7.1 , vous avez la possibilité d'inclure des fonctions d'agrégation (SUM,AVG,MIN,MAX) dans un index EVI.
CREATE ENCODED VECTOR INDEX EVI01 ON COMMANDES
(DATCMD, FAM)
INCLUDE (SUM(QTE) , COUNT(*) )
Avec le groupe PTF SF99701 level 18,ou la 7.2, les requêtes utilisant GROUPING SET, ROLLUP ou CUBE, bénéficient aussi de ce type d'index.
Enfin, depuis la TR3(7.2) / TR11 (7.1), si l'existe un index EVI pour chaque colonne retournée, SQE n'utilisent que des index EVI,
y compris pour faire la projection (liste des colonnes)

S'il existe un EVI sur HOST, il n'est pas utile de lire la table, le rapprochement des deux vecteurs permet d'aller lire la donnée dans le deuxième EVI

Cette technique, nommé EVI Only Access est automatique en 7.2.
Il faut utiliser l'option ALLOW_EVI_ONLY_ACCESS dans QAQQINI en 7.1
- Les index EVI doivent tenir en mémoire (fair share = mémoire du pool / nbr de travaux actifs dans le pool)
- Les index ne doivent porter que sur une seule colonne
- Toutes les colonnes du SELECT doivent avoir un index EVI.
©AF400