Bonjour,
Nous avons actuellement sur notre serveur de production deux tables définies comme cela:
L'idée est d'avoir une table contenant l'ensemble des plans de tri et la seconde contient les evènements historisés sur chacun d'entre eux. On n'utilise plus de champ 'etat' directement dans la table.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 CREATE TABLE [PLAN_TRI]( [NO_PLAN_TRI] [INT] IDENTITY(1,1) NOT NULL, [DATE_CREATION] [DATETIME] NOT NULL, [CODE_PLAN_TRI] [VARCHAR](50) NOT NULL, [LIBELLE] [VARCHAR](50) NULL, CONSTRAINT [PK_PLAN_TRI_NO_PLAN_TRI] PRIMARY KEY CLUSTERED ( [NO_PLAN_TRI] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO CREATE TABLE [EVENEMENT_PLAN_TRI]( [NO_EVENEMENT_PLAN_TRI] [INT] IDENTITY(1,1) NOT NULL, [NO_PLAN_TRI] [INT] NOT NULL, [ETAT_PLAN_TRI] [TINYINT] NOT NULL, [DATE_EVENEMENT] [DATETIME] NOT NULL, [NO_UTILISATEUR] [INT] NULL, CONSTRAINT [PK_EVENEMENT_PLAN_TRI_NO_EVENEMENT_PLAN_TRI] PRIMARY KEY CLUSTERED ( [NO_EVENEMENT_PLAN_TRI] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO ALTER TABLE [EVENEMENT_PLAN_TRI] WITH CHECK ADD CONSTRAINT [FK_EVENEMENT_PLAN_TRI_ETAT_PLAN_TRI] FOREIGN KEY([ETAT_PLAN_TRI]) REFERENCES [ETAT_PLAN_TRI] ([ETAT_PLAN_TRI]) GO ALTER TABLE [EVENEMENT_PLAN_TRI] CHECK CONSTRAINT [FK_EVENEMENT_PLAN_TRI_ETAT_PLAN_TRI] GO ALTER TABLE [EVENEMENT_PLAN_TRI] WITH CHECK ADD CONSTRAINT [FK_EVENEMENT_PLAN_TRI_NO_PLAN_TRI] FOREIGN KEY([NO_PLAN_TRI]) REFERENCES [PLAN_TRI] ([NO_PLAN_TRI]) GO ALTER TABLE [EVENEMENT_PLAN_TRI] CHECK CONSTRAINT [FK_EVENEMENT_PLAN_TRI_NO_PLAN_TRI] GO
Les indexes posé sur cette table sont :
Le problème c'est que les applications utilisant la base on besoin de connaitre très souvent le type du dernier evenement survenu sur un plan de tri.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 CREATE NONCLUSTERED INDEX [IX_EVENEMENT_PLAN_TRI_ETAT_PLAN_TRI] ON [EVENEMENT_PLAN_TRI] ( [ETAT_PLAN_TRI] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO CREATE NONCLUSTERED INDEX [IX_EVENEMENT_PLAN_TRI_NO_PLAN_TRI] ON [EVENEMENT_PLAN_TRI] ( [NO_PLAN_TRI] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO CREATE NONCLUSTERED INDEX [IX_DATE_EVENEMENT] ON [EVENEMENT_PLAN_TRI] ( [NO_PLAN_TRI] ASC [DATE_EVENEMENT]ASC ) INCLUDE (ETAT_PLAN_TRI) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO
Pour cela on effectue une requete du genre (codée dans une vue pour utiliser toujours la même dans les applications):
Et le problème c'est que nous n'arrivons pas à supprimer le full scan lors de cette requete.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 WITH CTE_EPT AS ( SELECT EPT.NO_PLAN_TRI , MAX( EPT.DATE_EVENEMENT ) MAX_DATE_EVENEMENT FROM EVENEMENT_PLAN_TRI EPT INNER JOIN PLAN_TRI PTR ON PTR.NO_PLAN_TRI = EPT.NO_PLAN_TRI GROUP BY EPT.NO_PLAN_TRI ) , CTE_PTR AS ( SELECT EPT.NO_PLAN_TRI FROM CTE_EPT INNER JOIN EVENEMENT_PLAN_TRI EPT ON CTE_EPT.NO_PLAN_TRI = EPT.NO_PLAN_TRI AND CTE_EPT.MAX_DATE_EVENEMENT = EPT.DATE_EVENEMENT AND EPT.ETAT_PLAN_TRI = 2 -- Etat en cours ) SELECT PTR.NO_PLAN_TRI , PTR.DATE_CREATION , PTR.CODE_PLAN_TRI , PTR.LIBELLE FROM PLAN_TRI PTR INNER JOIN CTE_PTR ON CTE_PTR.NO_PLAN_TRI = PTR.NO_PLAN_TRI
L'index utilisé pour cela est bien celui sur la date mais il y a invariablement un scan...
J'ai également essayé de supprimer le MAX et d'utiliser un row_number, mais le résultat est le même, voire moins performant...
peut on l'éviter ou bien est ce impossible à cause du max ?
Merci pour votre aide
Partager