Bonjour
sur la table suivante
Je veux impléménter une recherche exacte ou approchée qui me renvoie
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 CREATE TABLE [dbo].[T_ARTICLES_ART]( [ART_ID] [bigint] IDENTITY(1,1) NOT NULL, [ART_STYPE] [smallint] NULL, [ART_FAMILLE] [dbo].[D_FAMILLE_ARTICLE] NULL, [ART_REF_CONSTR] [dbo].[D_REF_ARTICLE] NULL, [ART_LIBELLE] [dbo].[D_LIBELLE_ARTICLE] NULL, [ART_PU] [dbo].[D_MT_MONETAIRE] NULL, [ART_PU_BASE] [dbo].[D_MT_MONETAIRE] NULL, [ART_CODIF_MARCHE] [varchar](48) COLLATE French_CS_AS NULL CONSTRAINT [PK_T_ARTICLES_ART] PRIMARY KEY CLUSTERED ( [ART_ID] ASC )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY] GO
- Une ligne recherchée sur Famille + Ref ou sur Famille + libelle
- x lignes avant
- x lignes après
notez que les x lignes et la ligne centrale ne sont donc pas forcement reliées
J'ai esayé 2 méthodes
Créer des champs "computed" non persistant sur la table soit
Avec un index sur chaque
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 CAST(ART_FAMILLE AS CHAR(16)) + ART_REF_CONSTR AS ART_CP_FAMREF CAST(ART_FAMILLE AS CHAR(16)) + ART_LIBELLE AS ART_CP_FAMLIB
et avec le code suivant partie d'une procedure stockée
J'obtiens une réponse quasi instantanée (4 ms) sur une table de 1 millions d'articles
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 DECLARE @P_TOP INT DECLARE @P_FAMILLE VARCHAR(16) DECLARE @P_REF VARCHAR(48) SET STATISTICS IO ON SET STATISTICS TIME ON SET @P_TOP = 50; SET @P_FAMILLE = 'LEGR'; SET @P_REF = '011'; -- recherche exacte sur famille , approchée sur ref WITH Ta AS ( SELECT TOP 1 ART_ID, ART_CP_FAMREF FROM dbo.T_ARTICLES_ART WHERE ART_CP_FAMREF LIKE CAST(@P_FAMILLE AS CHAR(16)) + @P_REF + '%' ORDER BY ART_CP_FAMREF ), TTa AS ( SELECT TOP (@P_TOP) A1.ART_ID FROM dbo.T_ARTICLES_ART A1 INNER JOIN Ta AS T1 ON A1.ART_CP_FAMREF < T1.ART_CP_FAMREF ORDER BY A1.ART_CP_FAMREF DESC UNION ALL SELECT TOP (@P_TOP + 1) A2.ART_ID FROM dbo.T_ARTICLES_ART A2 INNER JOIN Ta AS T2 ON A2.ART_CP_FAMREF >= T2.ART_CP_FAMREF ORDER BY A2.ART_CP_FAMREF ) SELECT T.ART_ID, T.ART_STYPE, T.ART_FAMILLE, T.ART_REF_CONSTR, T.ART_LIBELLE, T.ART_PU, T.ART_PU_BASE, T.ART_CODIF_MARCHE, T.ART_ATTRIB_E, T.ART_DACRE, T.ART_DAMAJ, T.ART_USERCRE, T.ART_USERMAJ FROM TTa INNER JOIN T_ARTICLES_ART AS T ON (TTa.ART_ID = T.ART_ID) ORDER BY T.ART_FAMILLE, T.ART_REF_CONSTR;
Mais si (solution que je trouve plus propre) je crée une vue sur la table article et comportant ART_ID + les 2 champs calculés comme
précédemment, avec un index cluster unique sur ART_ID et avec un index sur chaque autre champ
J'obtiens cette fois une réponse après 1700 ms sur une requête de même type (sauf que les cte portent cette fois sur la vue)
Je voudrais savoir si la méthode par computed column est correcte dans le cas d'une utilisation en production ,et le pourquoi de cette moins bonne vélocité de la vue indexée
Merci
Partager