Bonjour,
C'est un problème récurrent et il existe trois façons de le résoudre :
- soit vous faites un INSERT dans une table à deux colonnes, réservée à cet effet : l'une est un identifiant de type uniqueidentifier, généré par la procédure stockée avec la fonction NEWSEQUENTIALID(), et vous stockez toutes les valeurs dans cette colonne.
Ensuite vous faites la jointure sur cette table en filtrant par l'identifiant
- soit vous utilisez des paramètres de type TABLE (TVP dans la littérature), qui sont plus stricts.
Mais comme ce sont des variables de type TABLE côté SQL Server, aucune statistique n'est maintenue sur une telle table (elle est stockée dans TempDB).
Donc l'estimation de cardinalité pour un grand nombre de valeurs est souvent faux à moins que vous terminiez la requête par OPTION (RECOMPILE).
Dans ce dernier cas, si la requête est exécutée très fréquemment, vous allez augmenter la consommation de CPU.
- Soit vous utilisez une fonction SQL de dépouillement de la chaîne, et vous faites une jointure sur la fonction table.
Vous aurez le même problème d'estimation de cardinalité que ci-dessus.
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
| CREATE TABLE dbo.nombre
(
nombre int NOT NULL CONSTRAINT PK_Nombres PRIMARY KEY CLUSTERED
)
SET NOCOUNT ON
DECLARE @max AS INT,
@i AS INT
SELECT @max = 100000;
, @i = 1;
WHILE @i<= @max
BEGIN
INSERT dbo.nombre SELECT @i
SET @i += 1
END
CREATE FUNCTION dbo.SplitStringToInt
(
@string AS VARCHAR(max)
)
RETURNS TABLE
AS
RETURN
SELECT CAST(SUBSTRING(@string, nombre, CHARINDEX(',', @string + ',', nombre) - nombre) AS int) AS element
FROM dbo.nombre
WHERE nombre<= LEN(@string) + 1
AND SUBSTRING(',' + @string, nombre, 1) = ','
GO |
@++
![;)](https://www.developpez.net/forums/images/smilies/icon_wink.gif)
Partager