Bonjour

sur la table suivante
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
Je veux impléménter une recherche exacte ou approchée qui me renvoie
- 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

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
Avec un index sur chaque
et avec le code suivant partie d'une procedure stockée
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;
J'obtiens une réponse quasi instantanée (4 ms) sur une table de 1 millions d'articles

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