我有一个包含5个参数@State,@StartDate,@EndDate,@AsOfDate,@SICCode
的SP。如果我执行SP并提供参数,则返回数据〜1秒。
然后,如果我添加另一个参数@Coverage
,那么执行它需要大约17秒。
我查看了带有和不带@Coverage
参数的缓存计划,看起来它看起来一样。
我使用了调优顾问并创建了所有可能的索引。
如果我运行与SELECT
语句相同的代码并提供与WHERE
子句中的参数相同的值 - 那么我得到的结果约为1秒。
那么为什么只有当我添加这个确切的参数@Coverage时,它才会显着降低性能?
如果它是一个参数嗅探,那么我怎么能确定它是?有什么方法可以检查吗?
ALTER PROCEDURE [dbo].[EarningPlazaCommercial]
@State varchar(50),
@StartDate datetime,
@EndDate datetime,
@AsOfDate datetime,
@SICCode nvarchar(max),
@Coverage varchar(100)
AS
BEGIN
SET NOCOUNT ON;
CREATE TABLE #PolicyNumbers (PolicyNumber varchar(50))
INSERT INTO #PolicyNumbers SELECT PolicyNumber FROM PlazaInsuranceWPDataSet WHERE SICCode IN (SELECT * FROM [dbo].[StringOfStringsToTable](@SICCode,','))-- ('0161','0173','0179','0181','0191','0722','0752','0761','0782','1440','1441','1442','1521','1522','161','1611','1629','1711','172','1731','1742')
CREATE CLUSTERED INDEX IDX_C_PolicyNumbers_PolicyNumber ON #PolicyNumbers(PolicyNumber)
; WITH Earned_to_date AS (
SELECT Cast(@AsOfDate AS DATE) AS Earned_to_date
), policy_data AS (
SELECT
PolicyNumber,
Coverage
, Cast(PolicyEffectiveDate AS DATE) AS PolicyEffectiveDate
, Cast(PolicyExpirationDate AS DATE) AS PolicyExpirationDate
, WrittenPremium
--, --State
FROM PlazaInsuranceWPDataSet piwp
WHERE EXISTS (SELECT PolicyNumber FROM #PolicyNumbers pn WHERE pn.PolicyNumber = piwp.PolicyNumber)
AND Coverage IN (SELECT * FROM [dbo].[StringOfStringsToTable](@Coverage,','))
AND State IN (SELECT * FROM [dbo].[StringOfStringsToTable](@State,','))
)...
这是我正在使用的数据:
答案 0 :(得分:1)
这是因为你正在处理字符串。没有索引。逻辑复杂。
您应该整理列(make database normalization
)。你索引。
你应该使用集合论而不是使用组合字符串。
如果你不想改变你的qry,那么改变执行计划,重写为派生的qry。
select *
from (select ...) t
where Coverage (SELECT KeyCol FROM [dbo].[StringOfStringsToTable](@Coverage,','))
请尽量避免使用*
。
答案 1 :(得分:0)
而不是
WHERE EXISTS (SELECT PolicyNumber FROM #PolicyNumbers pn WHERE pn.PolicyNumber = piwp.PolicyNumber)
AND Coverage IN (SELECT * FROM [dbo].[StringOfStringsToTable](@Coverage,','))
AND State IN (SELECT * FROM [dbo].[StringOfStringsToTable](@State,','))
我插入了#PolicyNumbers
中所有参数过滤的所有政策号码
然后使用
WHERE EXISTS (SELECT PolicyNumber FROM #PolicyNumbers pn WHERE pn.PolicyNumber = piwp.PolicyNumber)
结果显示在~1秒