Hello les gens,
Mon problème du jour concerne les performances sur reporting services. J’ai sur le report, 4 sous rapport graphiques. Malheureusement 1 des 4 prends énormément de temps du genre 155 secondes pour du TimeDataRetrieval alors que le TimeProcessing et le TimeRendering tournent autour des 10 ms. Et donc je me retrouve avec un temps de traitement de 7 min pour l’affichage du rapport.
En gros, quel est le meilleur moyen d’optimiser un report sachant qu’il y a environ 17 000 lignes en base de données. Dois je passer sur le ReportManager pour jouer avec les différents modes de rendu, ou bien de revoir ma requete SQL sachant que cette dernière est composé de la même requete réitéré à 5 reprises.
[sql](select count(accountid)
from filteredaccount where new_statutprescripteur in (6,7) and statuscode = 1
and(@Var1 IS NULL OR CAST(ownerid AS VARCHAR(36)) = @Var1) AND (@Var2 IS NULL OR FilteredAccount.ownerid in (
SELECT systemuserid
from FilteredSystemuser where FilteredSystemuser.businessunitid = @Var2)) AND (@Var3 IS NULL OR @Var2 IS NOT NULL OR FilteredAccount.ownerid in (
SELECT systemuserid
from FilteredSystemuser where FilteredSystemuser.businessunitid in (
select businessunitid
from Filteredbusinessunit where parentbusinessunitid = @Var3)))
) Nb machins[/sql]
Y’a que moi qu’elle choque cette requête ? Des sous requêtes au lieu de simples jointures ?
D’ailleurs sur ton utilisation du @Machin IS NULL OR Truc = @Machin, c’est peu conseillé (cf. ce blog). En gros, dans le cas des paramètres optionels, si les performances ont une importance tu n’as pas le choix : il te faut faire autant de requête paramétrées que de combinaisons possible. C’est largement possible dans ton cas où tu n’as que 2 ou 3 paramètres.
Et je te conseille de lancer ta requête dans sql manager et d’afficher le plan d’exécution, et de tenter de faire quelque chose pour ces sous requetes.
Sinon question classique : tu as des index sur les colonnes sur lesquelles tu effectues ton filtrage (FilteredAccount.OwnerId, FilteredSystemUser.BusinessUnitId) ?
Il semblerait que tu cherches à faire une requête qui renvoie les comptes par id de OwnerId (@Var1), par id de “BusinessUnit” (@Var2) ou par id de “BusinessUnit parente” (@Var3), pourquoi pas une requête pour chaque cas ? Tu peux avoir des cas où plusieurs de ces paramètres sont fournis ?
T’as aussi un truc qui ressemble à une conversion de Guid (passage par un varchar). Pourquoi ?
Raaah, excellent, je me disais bien qu’il y avait une couille avec cette commande. Cela dit, je confirmerai toussa un peu plus tard. Je l’ai laissé de coté sachant que j’ai plus important pour l’instant. En tout cas, merci.
Edit: la requete n’est pas de moi, je fais juste des évolutions sur un projet et je viens de voir que les perf sont catastrophiques.
Edit bis: Alors oui, mes 3 variables peuvent etre renseignés ou pas. Il s’agit en fait de valeurs retournés par les listes déroulantes du formulaire du report. Les tables FilteredMaTable sont en quelques sortes des interfaces (je ne connais pas trop les termes) qui pointent vers les tables MaTable. Cette dernière est vérouillée pour plus de sécurité (Microsoft CRM).
Pour la conversion du Guid, je ne sais pas.
Bon, j’ai blocage. La requete n’est pas dans une procédure stockée et je ne sais pas si un rapport Reporting Services peut etre assigné à une procédure stockée et si oui, j’aimerais éviter de mettre la procédure dans la base mais plutot directement dans le fichier rdl du rapport.
Deuxièmement, en fouillant sur le web, je suis tombé sur l’instruction CASE THEN ELSE
Le problème c’est qu’aucun des sites ne mentionnent s’il est possible de mettre une requete SQL au lieu d’une expression. (Cela dit, je n’ai pas encore testé, je vais pas tarder à partir).
Pour rappel, la requete SQL est sous cette forme :
SELECT (Grosse requete ci-dessus) As Champ1, (Grosse requete idem) As Champ2, (Grosse requete idem) As Champ 3
Voilà. Si on peut m’éclairer dessus ca m’évitera d’y penser la nuit :).
Je reviens sur la chose pour dire que j’ai enfin pu optimiser mon rapport d’un ratio de 3 voir 5. Au lieu d’attendre 10 min, il me faut un maximum de 3 min tout rond. Maintenant, je cherche à optimiser le TimeProcessing et comme j’ai perdu les liens qui m’intéressaient, je voulais savoir si l’un d’entre vous aurez pas un conseil pour optimiser cette chose ?