J'ai créé une fonction définie par l'utilisateur pour obtenir des performances avec les requêtes contenant 'WHERE col IN (...)', comme ce cas:fonction définie par l'utilisateur remplaçant WHERE IN col (...)
SELECT myCol1, myCol2
FROM myTable
WHERE myCol3 IN (100, 200, 300, ..., 4900, 5000);
Le les requêtes sont générées à partir d'une application web et sont dans certains cas beaucoup plus complexes. La définition de la fonction ressemble à ceci:
CREATE FUNCTION [dbo].[udf_CSVtoIntTable]
(
@CSV VARCHAR(MAX),
@Delimiter CHAR(1) = ','
)
RETURNS
@Result TABLE
(
[Value] INT
)
AS
BEGIN
DECLARE @CurrStartPos SMALLINT;
SET @CurrStartPos = 1;
DECLARE @CurrEndPos SMALLINT;
SET @CurrEndPos = 1;
DECLARE @TotalLength SMALLINT;
-- Remove space, tab, linefeed, carrier return
SET @CSV = REPLACE(@CSV, ' ', '');
SET @CSV = REPLACE(@CSV, CHAR(9), '');
SET @CSV = REPLACE(@CSV, CHAR(10), '');
SET @CSV = REPLACE(@CSV, CHAR(13), '');
-- Add extra delimiter if needed
IF NOT RIGHT(@CSV, 1) = @Delimiter
SET @CSV = @CSV + @Delimiter;
-- Get total string length
SET @TotalLength = LEN(@CSV);
WHILE @CurrStartPos < @TotalLength
BEGIN
SET @CurrEndPos = CHARINDEX(@Delimiter, @CSV, @CurrStartPos);
INSERT INTO @Result
VALUES (CAST(SUBSTRING(@CSV, @CurrStartPos, @CurrEndPos - @CurrStartPos) AS INT));
SET @CurrStartPos = @CurrEndPos + 1;
END
RETURN
END
La fonction est destinée à être utilisée comme celui-ci (ou comme INNER JOIN):
SELECT myCol1, myCol2
FROM myTable
WHERE myCol3 IN (
SELECT [Value]
FROM dbo.udf_CSVtoIntTable('100, 200, 300, ..., 4900, 5000', ',');
Avez-ce que quelqu'un a des idears de optimiztion de ma fonction ou autre façons d'améliorer les performances dans mon cas? Y at-il des inconvénients que j'ai manqués? J'utilise le framework MS SQL Server 2005 Std et .NET 2.0.
+1 pour une bonne suggestion, mais je vais utiliser une version qui gère BIGINT aussi bien et la table de nombre augmentera beaucoup! –
La table Nombre doit seulement être aussi grande que la plus longue chaîne. Si vous prévoyez d'avoir plus de 8000 caractères dans la chaîne fractionnée, ajoutez simplement plus de lignes.Le nombre d'int dans la table de nombre peut aller jusqu'à 2 147 483 647 et je doute fort que vous ayez une chaîne aussi longue. –