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 :
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
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
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
(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)
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.