|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | |||
![]() ![]() Alexandre ChemlaConsultant en Business Intelligence Inscription : février 2006 Messages : 1 773 ![]() |
Bonjour,
Dans le cadre d'un reporting décisionnel, j'ai une requête relativement complexe à réaliser. Le principe est de récupérer des données d'un certain périmètre depuis ma table de faits, avec des jointures sur les tables de dimensions, des regroupements pour des sommes etc. Ce sont des données de vente que je stocke au niveau le plus fin. Ensuite, une fois que j'ai ces données de mon périmètre je fais dessus différents différents select avec des niveaux de groupements différents que j'empile avec des UNION ALL. Je n'ai pas la main sur le modèle de données et je ne peux pas non plus réaliser mes agrégations dans le reporting, les données présentant des particularités. Bref, ma première idée était d'utiliser 1 requête unique avec des CTE, ensuite vu les temps de traitements, j'ai essayé avec une table temporaire, tout ce qu'il y a de plus simple. v1 : Uniquement le select de base pour définir mon périmètre v2 : CTE pour le périmètre puis CTE sur celle-ci pour les différents niveaux de vente v3 : select de base INTO #tt et ensuite CTE sur cette table temporaire. Voici les temps UC des différentes versions : Citation:
Plutôt qu'une table temporaire, je pourrais utiliser une vrai table mais ce qui m'étonne est le constat de base. A part que ma requête peut largement être améliorée, que faut-il en penser ? je pensais être plus efficace avec la CTE qu'une simple table temporaire ? La mémoire de mon instance est-elle saturée ? Il n'y a pourtant que 35 000 lignes environ. Merci. Pour info, la requête complète : Code :
|
|||
|
|
00
|
|
|
#2 | ||
![]() ![]() |
Vous pouvez éviter tous les union all avec le ROLLUP.
Un exemple à adapter : Code :
__________________
Email : http://scr.im/waldar |
||
|
00
|
|
|
#3 |
![]() ![]() ![]() Nicolas SouquetAdministrateur de base de données Inscription : janvier 2005 Messages : 4 669 ![]() |
Bonjour,
Il n'y a pas de récursivité dans vos expressions de table commune puisqu'il n'y a jamais de jointure entre une ancre et une partie récursive de celles-ci. Les CTE récursives peuvent produire des plans aux cardinalités foireuses si la jointure a une cardinalité bien supérieure à 1. @++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes. Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012 |
|
00
|
|
|
#4 |
![]() ![]() Alexandre ChemlaConsultant en Business Intelligence Inscription : février 2006 Messages : 1 773 ![]() |
Merci pour le ROLLUP, ce sera effectivement une bonne chose.
Pour la récursivité, je n’utilise effectivement pas. Les CTE ne sont "intéressantes" qu'en cas de récurcivité ? |
|
|
00
|
|
|
#5 |
![]() ![]() |
Je les utilise aussi en lieue et place de vue imbriquée, je trouve la compréhension des requêtes plus aisées ainsi.
__________________
Email : http://scr.im/waldar |
|
00
|
|
|
#6 |
![]() ![]() Alexandre ChemlaConsultant en Business Intelligence Inscription : février 2006 Messages : 1 773 ![]() |
Je préférais aussi par une requête unique, compréhensible, travaillant uniquement en mémoire etc. plutôt que de passer par exemple par une table temporaire.
Cette différence de performance n'est-elle pas bizarre ? |
|
|
00
|
|
|
#7 | ||||
![]() ![]() ![]() Frédéric BROUARDExpert SGBDR & SQL Inscription : mai 2002 Messages : 10 954 ![]() |
Sans la définition de vos tables et des index il est impossible de vous aider plafonnement.
Une solution plus efficace est de ne véhiculer les détails que dans la requête finale après agrégation. Exemple : Code :
Code :
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/ Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp. Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation * * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * * |
||||
|
00
|
|
|
#8 | |||||
|
Membre chevronné
![]() ![]() Inscription : juillet 2006 Messages : 1 194 ![]() |
Une CTE ne provoque pas en lui-même de query.
Càd que si vous avez CTE1, CTE2, QUERY : CTE1 ne sera ni "fait" en premier ni indépendamment de QUERY, CTE2 ne ser ni "fait" en second ni indépendamment de QUERY, et d'ailleurs si CTE1 et CTE2 ne sont pas employés dans QUERY, ces dernières n'auront aucun effet et seront simplement "ignorées". Voyez une CTE comme du SQL que vous choisissez d'écrire une fois à un endroit pour l'insérer ailleurs une ou plusieurs fois (mais ne voyez pas que ça, la récursivité est une possibilité importante offerte par les CTE). Citation:
|
|||||
|
|
00
|
|
|
#9 |
![]() ![]() Alexandre ChemlaConsultant en Business Intelligence Inscription : février 2006 Messages : 1 773 ![]() |
Je sais que sans le modèle complet c'est plus compliqué à évaluer, mais plutôt que de me fournir une requête toute belle, c'était déjà pour les idées et concepts de ces objets.
Merci pour la précisions sur les CTE, je pensais que le résultat de la requête était d'abord mis en mémoire, puis utilisé x-fois dans mes différentes requêtes suivantes. c'est vrai que lorsque je regarde le plan d’exécution, les tables de ma requête de base sont visible un certains nombre de fois. |
|
|
00
|
|
|
#10 | |
![]() ![]() ![]() Frédéric BROUARDExpert SGBDR & SQL Inscription : mai 2002 Messages : 10 954 ![]() |
Citation:
A +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/ Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp. Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation * * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * * |
|
|
00
|
|
|
#11 |
|
Membre chevronné
![]() ![]() Inscription : juillet 2006 Messages : 1 194 ![]() |
|
|
|
00
|
|
|
#12 |
![]() ![]() Alexandre ChemlaConsultant en Business Intelligence Inscription : février 2006 Messages : 1 773 ![]() |
Mis à part passer par une table temporaire, et ne pouvant créer une table d'agrégats, de quels autres moyens est-ce que je dispose pour éviter les CTE qui, non récursives mais simplement utilisées plusieurs fois, ne sont pas vraiment l'idéal ?
|
|
|
00
|
|
|
#13 |
![]() ![]() |
Cf. ma première réponse, vous n'avez besoin ici ni de CTE, ni de table temporaire.
Il ne faut que réécrire la requête avec l'utilisation du ROLLUP.
__________________
Email : http://scr.im/waldar |
|
00
|
|
|
#14 | ||||
![]() ![]() Alexandre ChemlaConsultant en Business Intelligence Inscription : février 2006 Messages : 1 773 ![]() |
Hummm oui, c'est vrai que ça marche dans ce cas... mais prenons un autre exemple
Cette fois je récupère les ventes de tous mes points de ventes, par gamme. Ensuite je calcule dessus un top et un flop, mais par regroupement de ces gammes. je dois alors restituer le top/flop par regroupement mais conserver l'information du détail de la gamme. De la même manière j'avais une CTE pour récupérer le périmètre, 1 pour calculer les top/flop et un select de jointure pour la restitution. Sur ce périmètre plus réduit, je passe tout de même de Citation:
Citation:
Code :
|
||||
|
|
00
|
|
|
#15 |
![]() ![]() Alexandre ChemlaConsultant en Business Intelligence Inscription : février 2006 Messages : 1 773 ![]() |
Je vois que cette dernière digression vers une requête n'a pas beaucoup inspirée les foules...
Je reviens donc sur la première et l'idée du ROLLUP. En fait je me souvient pourquoi je ne peux l'utiliser. Le problème est que, malgré les niveaux hiérarchiques de la requête (groupement > secteur > région etc.), chacun des niveaux est filtré. L'utilisateur filtre chacun des niveaux ; mais il peut très bien vouloir restituer 1 seul groupement mais par contre il souhaite toujours voir le total du secteur (tous groupements confondus) auquel appartient ce groupement. L'idée serait peut-être alors de restituer chacun des niveaux au complet, de manière plus simple et sûrement plus rapide, puis de filtrer ensuite l'affichage dans l'outil de reporting ?
__________________
Alexandre Chemla - Consultant MS BI chez Masao |
|
|
00
|
|
|
#16 |
![]() ![]() |
Oui ce serait une idée, si vous écrivez juste le ROLLUP tous les sous-totaux sont effectués, après on peut effectivement en gérer l'affichage ou non.
Pour votre constat, difficile de tirer de grandes conclusions, on n'a ni vos données ni votre environnement... Vous dire pourquoi une table temporaire fonctionne mieux ici qu'une CTE, j'en suis bien incapable.
__________________
Email : http://scr.im/waldar |
|
00
|
Copyright © 2000-2012 - www.developpez.com