Introduction
Avec Sybase ASE 15, les clauses GROUP BY
et ORDER BY
ont été optimisées pour réaliser les opérations en mémoire grâce au hachage et éviter ainsi les matérialisations de tables de travail dans tempdb (worktables) pour ces opérations.
Par défaut pour des tables classiques (car ce n’est pas systématique), dans les versions pre 15.0 d’Adaptive Server Enterprise, le résultat est trié pour une requête avec une clause GROUP BY
sans avoir à spécifier une clause ORDER BY
, le tri étant réalisé sur les colonnes de la clause GROUP BY
.
Avec le hachage, le résultat d’une requête avec une clause GROUP BY
ne retourne plus forcément un jeu de résultats déjà trié sur les colonnes dans la clause GROUP BY
, ce qui peut être très pénalisant pour les applications existantes n’ayant jamais spécifié de clauses ORDER BY
. Un contournement de ce problème a été donné avec ASE 15.0 ESD#2 avec l’introduction d’un nouveau traceflag 450, mais le statut futur de ce traceflag dans les prochaines versions d’ASE 15 n’est toujours pas connu.
Contexte
La norme ANSI SQL spécifie que le tri d’un jeu de résultats n’est défini que par l’application d’une clause ORDER BY
. En aucun cas la clause GROUP BY
est astreinte à fournir un jeu de résultats déjà trié.
Contexte en fonction des versions ASE
Depuis les versions Sybase ASE 11.5 (parallélisme) et 11.9 (DOL row forwarding), la clause ORDER BY
est importante. Pour être plus précis, pour des tables partitionnées (round robin) ou en mode de verrouillage DOL (Datarows locking), le résultat d’une clause GROUP BY
n’est pas forcément trié et l’application de la clause ORDER BY
est indispensable.
Malheureusement, de mauvaises habitudes de développement ont été prises avec la clause GROUP BY
pour les tables non partitionnées en mode de verrouillage APL (Allpages ou datapages) dans les versions ASE antérieures à la version 15 : en effet, le tri dans ce contexte est toujours prévisible et le résultat de la clause GROUP BY
est toujours trié sur les colonnes de la clause GROUP BY
.
Avec ASE 15 et le traitement des clauses GROUP BY
en mémoire par hachage, l’ordre de tri du jeu de résultats retourné n’est absolument plus prévisible => régressions si l’ordre de tri sur les clés de la clause GROUP BY
était supposé implicitement par l’application.
Exemple
Voici un exemple.
Versions pre ASE 15.0 | Versions ASE 15.0 |
---|---|
|
|
Dans la version pre 15.0, le tri est assuré sur la colonne type, colonne de la clause GROUP BY
.
Dans la version 15.0, le tri n’est pas assuré sur la colonne type, colonne de la clause GROUP BY
.
Traceflag 450
Avec Sybase ASE 15.0 ESD#2, le traceflag (450) assure le tri sur les colonnes de la clause GROUP BY
:
dbcc traceon(450) go select count(*), type from sysobjects group by type go
type ----------- ---- 1 D 55 P 52 S 19 U 4 V
Conclusion
Le traceflag 450 n’est absolument pas documenté (ne serait ce que quelques lignes) pour décrire son fonctionnement (force-t-il l’optimiseur à utiliser les worktables dans tempdb comme dans les versions pre 15.0, ce qui revient à basculer vers l’ancien optimiseur ou force-t-il le tri après le group by
?).
Comment forcer le traceflag 450 pour toutes les sessions entrantes si malheureusement les régressions sont fatales pour les applications à cause des clauses GROUP BY
où le tri était implicite, car dans le dernier exemple il s’agit d’une session isql mais pour les autres couches de connexion (JDBC, PowerBuilder, etc.) la question demeure ? Autre question majeure, quelle est la position de Sybase à ce sujet (migration impérative des applications et procédures stockées avec ajout des clauses ORDER BY
ou bien l’optimiseur ASE 15 s’adaptera-t-il ?)
Ces questions seront posées à Sybase.