需要有關如何改進我的SQL腳本以獲得更好性能的幫助。 dbo.Products
表有百萬行。我很猶豫要用動態SQL重寫它。謝謝!逗號分隔值(CSV)參數過濾
DECLARE
@Brand varchar(MAX) = 'Brand 1, Brand 2, Brand 3',
@ItemCategory varchar(MAX) = 'IC1, IC2, IC3, IC4, IC5'
--will return all records if params where set to @Brand = NULL, @ItemCategory = NULL
SELECT
[Brand],
SUM([Amount]) AS [Amount]
FROM dbo.Products (NOLOCK)
LEFT JOIN [dbo].[Split](@Brand, ',') FilterBrand ON Brand = [FilterBrand].[Items]
LEFT JOIN [dbo].[Split](@ItemCategory, ',') FilterItemCategory ON ItemCategory = [FilterItemCategory].[Items]
WHERE
(@Brand IS NULL OR (@Brand IS NOT NULL AND [FilterBrand].[Items] IS NOT NULL)) AND
(@ItemCategory IS NULL OR (@ItemCategory IS NOT NULL AND [FilterItemCategory].[Items] IS NOT NULL))
GROUP BY
[Brand]
下面是拆分表值函數,我在網上找到:
CREATE function [dbo].[Split]
(
@String varchar(8000),
@Delimiter char(1)
)
RETURNS @Results TABLE (Items varchar(4000))
AS
BEGIN
IF (@String IS NULL OR @String = '') RETURN
DECLARE @i int, @j int
SELECT @i = 1
WHILE @i <= LEN(@String)
BEGIN
SELECT @j = CHARINDEX(@Delimiter, @String, @i)
IF @j = 0
BEGIN
SELECT @j = len(@String) + 1
END
INSERT @Results SELECT RTRIM(SUBSTRING(@String, @i, @j - @i))
SELECT @i = @j + LEN(@Delimiter)
END
RETURN
END
幾件事情:(1)你真** ** **需要ALL **從'Products'列?如果不是,請不要使用SELECT *,而是明確指定列的列表。這*可能會爲性能調整打開一個機會; (2)確保'JOIN'中涉及的所有列都被正確編入索引; – 2012-08-09 16:30:43
我最近記錄了一些更有效的方法來分割字符串:http://www.sqlperformance.com/2012/07/t-sql-queries/split-strings&http://www.sqlperformance.com/2012/ 08/t-sql-queries/splitting-strings-follow-up – 2012-08-09 16:45:38
@marc_s我修改了我的示例腳本。我在現實生活中不使用「SELECT *」...謝謝。 – peng 2012-08-09 16:56:42