Bizarrerie des temps d'exécution d'une requête
Bonjour à tous,
je travaille sur une base SQL2012 avec SQL Server Management studio.
J'ai une requête que je vous colle ci dessous :
Code:
1 2 3 4 5 6 7 8 9
|
SELECT TOP 1000000 e.* --distinct tmp.CompteGeneral
FROM ECRITURE E
INNER JOIN EXERCICE ON EXERCICE.DateOuverture <= '01/01/2016' AND EXERCICE.DateCloture >= '01/01/2016'
INNER JOIN JOURNAL ON JOURNAL.CodeJournal = E.CodeJournal
INNER JOIN PLANTIER ON PLANTIER.CompteTiers = E.CompteTiers
--CROSS APPLY dbo.Ecriture_ResteARegler(E.NumEcriture) AS fnEcr
WHERE E.CompteTiers <> '' AND PLANTIER.TypeCompteTiers = 'C'
AND E.DatePassation >= EXERCICE.dateouverture |
Temps d'exécution : 1 seconde.
12 000 lignes renvoyées pour 350 000 enregistrements dans la table ECRITURE.
J'ajoute une jointure sur une fonction table :
Code:
1 2 3 4 5 6 7 8 9
|
SELECT e.* --distinct tmp.CompteGeneral
FROM ECRITURE E
INNER JOIN EXERCICE ON EXERCICE.DateOuverture <= '01/01/2016' AND EXERCICE.DateCloture >= '01/01/2016'
INNER JOIN JOURNAL ON JOURNAL.CodeJournal = E.CodeJournal
INNER JOIN PLANTIER ON PLANTIER.CompteTiers = E.CompteTiers
CROSS APPLY dbo.Ecriture_ResteARegler(E.NumEcriture) AS fnEcr
WHERE E.CompteTiers <> '' AND PLANTIER.TypeCompteTiers = 'C'
AND E.DatePassation >= EXERCICE.dateouverture |
Je passe à 25 secondes.
Je peux comprendre : une fonction, ça coute...
Je bricole un peu ma requete pour essayer d'arranger les choses :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
SELECT * --distinct tmp.CompteGeneral
FROM (
select
E.NumEcriture, e.CompteGeneral
FROM ECRITURE E
INNER JOIN EXERCICE ON EXERCICE.DateOuverture <= '01/01/2016' AND EXERCICE.DateCloture >= '01/01/2016'
INNER JOIN JOURNAL ON JOURNAL.CodeJournal = E.CodeJournal
INNER JOIN PLANTIER ON PLANTIER.CompteTiers = E.CompteTiers
WHERE E.CompteTiers <> '' AND PLANTIER.TypeCompteTiers = 'C'
AND E.DatePassation >= EXERCICE.dateouverture
) as tmp
CROSS APPLY dbo.Ecriture_ResteARegler(Tmp.NumEcriture) AS fnEcr |
Sans trop de succès.
J'essaie sans succès d'ajouter OPTION (FORCE ORDER) pour l'obliger à n'évaluer le résultat de la fonction que quand c'est nécessaire.
Et là, par hasard, je tente un truc :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
SELECT * --distinct tmp.CompteGeneral
FROM (
select TOP 1000000
E.NumEcriture, e.CompteGeneral
FROM ECRITURE E
INNER JOIN EXERCICE ON EXERCICE.DateOuverture <= '01/01/2016' AND EXERCICE.DateCloture >= '01/01/2016'
INNER JOIN JOURNAL ON JOURNAL.CodeJournal = E.CodeJournal
INNER JOIN PLANTIER ON PLANTIER.CompteTiers = E.CompteTiers
WHERE E.CompteTiers <> '' AND PLANTIER.TypeCompteTiers = 'C'
AND E.DatePassation >= EXERCICE.dateouverture
) as tmp
CROSS APPLY dbo.Ecriture_ResteARegler(Tmp.NumEcriture) AS fnEcr |
Ho miracle, je passe à 1 seconde.
Le seul changement c'est le TOP 1000000.
Je ne peux pas laisser ça comme ça, même si ça marche...
Quelqu'un peut éclairer ma lanterne et m'expliquer pourquoi ça fonctionne mieux ?
Merci d'avance,
Seb
EDIT : correction requete 3
PS : pour la fonction : je n'ai pas trop le choix vue le modèle de données (que je ne peux améliorer :calim2:)