Computed column ou vue indéxée
Bonjour
sur la table suivante
Code:
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:
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:
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