Hello,
Je me tourne vers vous car je ne sais pas trop quoi faire dans le cas présent. J'imagine bien que l'ajout d'un index devrait m'aider mais j'ai toujours beaucoup de mal à savoir le(s)quel(s) mettre en place...
J'ai donc la table suivante :
Sur laquelle j'ai ajouté la contrainte suivante (le code de la fonction suit celui de la contrainte) :
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 CREATE TABLE [S_PROMO].[T_PRODUCT_LIST_OWN_PLO]( [DTO_ID] [int] NOT NULL, [PLO_BARCODE] [char](13) NOT NULL, [PLO_INCLUSIVE] [bit] NOT NULL, [PLO_COLOR] [varchar](50) NULL, [PLO_SIZE] [varchar](50) NULL, [PLO_DESC] [varchar](50) NULL, [PLO_PRICE] [varchar](50) NULL, [PLO_CREATED_ON] [datetime] NOT NULL CONSTRAINT [DF__T_PRODUCT__PLO_C__5027A6DA] DEFAULT (getdate()), [PLO_CREATED_BY] [varchar](100) NOT NULL CONSTRAINT [DF__T_PRODUCT__PLO_C__511BCB13] DEFAULT (suser_sname()), [PLO_MODIFIED_ON] [datetime] NULL, [PLO_MODIFIED_BY] [varchar](100) NULL, [PLO_NSA] [varchar](50) NULL, [PLO_REF] [varchar](50) NULL, CONSTRAINT [PK_T_PRODUCT_LIST_OWN_PLO] PRIMARY KEY CLUSTERED ( [DTO_ID] ASC, [PLO_BARCODE] ASC )) ON [PRIMARY] GO ALTER TABLE [S_PROMO].[T_PRODUCT_LIST_OWN_PLO] WITH CHECK ADD CONSTRAINT [FK_PLO_TO_DTO] FOREIGN KEY([DTO_ID]) REFERENCES [S_PROMO].[T_DETAIL_OWN_DTO] ([DTO_ID]) ON DELETE CASCADE GO
(comme vous le voyez, j'ai déjà suspecté un problème de parameters sniffing, d'où la duplication des paramètres de la fonction en variables locales mais cela n'a pas résolu le problème, ce n'est donc pas ça je pense)
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 ALTER TABLE [S_PROMO].[T_PRODUCT_LIST_OWN_PLO] WITH NOCHECK ADD CONSTRAINT [CK_DOUBLE_PROMO] CHECK (([S_PROMO].[UF_CHECK_DOUBLE_EAN_OWN]([PLO_BARCODE],[DTO_ID])=(0))) GO CREATE FUNCTION [S_PROMO].[UF_CHECK_DOUBLE_EAN_OWN] (@BARCODE CHAR(13), @DTO_ID INT) RETURNS BIT AS BEGIN DECLARE @RESULT BIT; DECLARE @COUNT INT; DECLARE @PRM_ID INT; DECLARE @DTO_ID_BIS INT = @DTO_ID; DECLARE @BARCODE_BIS CHAR(13) = @BARCODE; SELECT @PRM_ID = PRM_ID FROM S_PROMO.T_DETAIL_OWN_DTO WHERE DTO_ID = @DTO_ID_BIS; SELECT @COUNT = COUNT(*) FROM S_PROMO.T_PRODUCT_LIST_OWN_PLO PLO INNER JOIN S_PROMO.T_DETAIL_OWN_DTO DTO ON PLO.DTO_ID = DTO.DTO_ID WHERE DTO.PRM_ID = @PRM_ID AND PLO.PLO_BARCODE = @BARCODE_BIS; IF @COUNT < 2 SET @RESULT = 0 ELSE SET @RESULT = 1 RETURN @RESULT; END
Le but étant d'empêcher, qu'au sein d'une même promo, un article soit repris deux fois (et recevrait alors 2 fois la promo --> pas bon pour le business)
La table S_PROMO.T_PRODUCT_LIST_OWN_PLO compte 213780 lignes. Vraiment pas grand chose donc.
Le problème se produit lorsque, via l'interface applicatif (.NET), l'utilisateur veut copier une promo. Cette copie impacte bien sûr tout un tas de table mais j'ai déjà pu, via l'outil "Activity monitor" de SSMS, circonscrire le problème à cette contrainte (d'ailleurs si je retire la contrainte, la copie de promo se passe bien). On parle, dans ce cas-ci, de 9531 lignes à insérer dans cette table. Cela ne me semble pas du tout gargantuesque (c'est l'inverse même)...
Pour diable alors cette contrainte fait-elle exploser le timeout ?
Si vous avez besoin d'autres codes DDL pour pouvoir vous prononcer, n'hésitez pas à demander.
Merci d'avance.
Partager