我有一个存储过程使用20个表检索数据。 样品的程序:如何优化这个动态存储过程
CREATE PROCEDURE GetEnquiries
(
@EnquiryDate DATETIME = NULL
)
AS
DECLARE @querySELECT VARCHAR(MAX) = ''
DECLARE @queryWHERE VARCHAR(MAX) = ''
DECLARE @queryExtraColumns VARCHAR(MAX) = ''
DECLARE @queryReturnResults VARCHAR(MAX) = ''
-----------------------------------------------------
--Create temp table
-----------------------------------------------------
SET @querySELECT = '
CREATE TABLE #tempResults
(
EnquiryId INT,
Cost Decimal(18,2),
CustomerName VARCHAR(50),
EnquiryStatus VARCHAR(50),
ContactNumber VARCHAR(50),
NumberOfVisits INT
) '
-----------------------------------------------------
--Insert into temp table
-----------------------------------------------------
SET @querySELECT = '
INSERT INTO #tempResults
(
EnquiryId ,
Cost ,
CustomerName ,
EnquiryStatus ,
ContactNumber
) '
-----------------------------------------------------
--SELECT
-----------------------------------------------------
SET @querySELECT = '
SELECT
e.EnquiryId ,
e.Cost ,
c.CustomerName ,
e.EnquiryStatus ,
c.ContactNumber
FROM Enquiry e
INNER JOIN Customers c ON e.CustomerId = c.CustomerId '
-----------------------------------------------------
-- WHERE
-----------------------------------------------------
IF(@EnquiryDate IS NOT NULL)
BEGIN
SET @queryWHERE = @queryWHERE + ' CONVERT(VARCHAR(10),e.EnquiryDate,23) >= ' + ''''+ CONVERT(VARCHAR(10),@EnquiryDate,23) + ''''
END
--- There are at least 14 parameters used in WHERE operation the above is just one of them
-----------------------------------------------------
-- Count NumberOfVisits
-----------------------------------------------------
SET @queryExtraColumns = '
;WITH NumberOfVisits AS
(
SELECT t.EnquiryId, COUNT(EnquiryId) AS NumberOfVisits
FROM NumberOfVisits v
INNER JOIN #tempResults t ON v.EnquiryId = t.EnquiryId
GROUP BY t.EnquiryId
)
UPDATE #tempResults
SET NumberOfVisits = u.NumberOfVisits
FROM #tempResults t
INNER JOIN NumberOfVisits u ON u.EnquiryId = t.EnquiryId
'
-----------------------------------------------------
-- return the results
-----------------------------------------------------
SET @queryReturnResults = '
SELECT
EnquiryId ,
Cost ,
CustomerName ,
EnquiryStatus ,
ContactNumber ,
NumberOfVisits
FROM #tempResults t
'
-----------------------------------------------------
-- Combine all the strings + DROP the temp table
-----------------------------------------------------
-- PRINT( @querySELECT + ' WHERE ' + @queryWHERE + @queryExtraColumns + @queryReturnResults + ' DROP TABLE #tempResults ')
EXEC(@querySELECT + ' WHERE ' + @queryWHERE + @queryExtraColumns + @queryReturnResults + ' DROP TABLE #tempResults ')
一些事实:
上述过程是存储过程我工作的简单形式。
我使用SQL Server 2008
我的实际过程有15个参数,所有的人都在WHERE子句中使用。如果为参数提供了该值,则该参数将包含在WHERE子句中,否则将包含该参数。
至少有10列值来自GROUP BY条件,如上述过程中给出的一个“NumberOfVisits”。
我有所有主键上的索引&外键。
我有在WHERE子句中使用的所有列的索引。
我有在GROUP BY子句中使用的所有列的索引。
问题:
Q1:这个是根据创建以下上面的图案动态存储过程的最佳做法?
Q2:我得到这个过程的输出SQL使用: - PRINT(@querySELECT + '其中' + @queryWHERE + @queryExtraColumns + @queryReturnResults + 'DROP TABLE #tempResults')当我运行 那SQL所用的时间与存储过程所花费的时间相同,为什么?不是SQL应该花更少的时间?为什么没有区别?
问题3:以上是获得汇总列值(“NumberOfVisits”)的最佳做法吗?
Q4:以上是动态创建WHERE子句的最佳方法吗?
问题5:我可以通过在上面的场景中使用一些替代方法来避免使用临时表吗?
Q6:我能做些什么来优化这个程序?
请原谅我,如果我的问题不清楚或不是一个适当的问题。
感谢您宝贵的时间&帮助。
[动态SQL的诅咒和祝福](http://www.sommarskog.se/dynamic_sql.html) – Oded