我有一个存储过程,可以在SQL Server 2005中批处理电话和地址
如果我在2小时内执行存储过程。但是,如果我运行相同的代码和相同的批处理,则需要2秒钟。
我尝试了以下步骤以加快速度,但它们没有奏效:
以下是基本代码
USE [MyDB]
GO
/****** Object: StoredProcedure [myschema].[ProccesBatch] Script Date: 06/30/2011 10:37:33 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [myschema].[ProccesBatch]
-- Add the parameters for the stored procedure here
(@BatchId int)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SET ANSI_NULLS ON;
-- AD Hoc TESTING ONLY. This gets uncommented when running ad hoc.
-- DECLARE @BatchId Int
-- SET @BatchId = 59
DECLARE @MyList AS VARCHAR (500)
DECLARE @MySICList AS VARCHAR (500)
DECLARE @MyType AS CHAR (1)
DECLARE @MyProvider AS VARCHAR (500)
DECLARE @MyState AS VARCHAR (2)
DECLARE @MyCityList AS VARCHAR (500)
DECLARE @MyZipList AS VARCHAR (500)
DECLARE @MyStyle AS VARCHAR (1)
DECLARE @MySource AS VARCHAR (150)
DECLARE @MyStartDate AS DATETIME
DECLARE @MyEndDate AS DATETIME
DECLARE @MyCampaign AS BIT
DECLARE @CheckExist AS INT
SET @CheckExist = 0
--
-- 1. Check if Campaign Exist.
--
SELECT
@CheckExist = Id
FROM myschema.Destination
WHERE Id = @BatchId
IF @CheckExist > 0
BEGIN
RAISERROR('Creation has already been processed', 16, 1)
RETURN
END
--
-- 2. Get Header and parameters for controlling process.
--
SELECT
@MyList = ISNULL(LeadBatchHeaderList,''),
@MySICList = ISNULL(SICCodeList,''),
@MyType = ISNULL(MyType,''),
@MyProvider = ISNULL(LDCList,''),
@MyState = ISNULL([State],''),
@MyCityList = ISNULL(CityList,''),
@MyZipList = ISNULL(ZipCodeList,''),
@MyStyle = ISNULL(Commodities,''),
@MySource = ISNULL(LeadSource,''),
@MyStartDate = ISNULL(HeaderCreationStart,''),
@MyEndDate = ISNULL(HeaderCreationEnd,''),
@MyCampaign = ISNULL(AllCampaign ,'')
FROM myschema.Header
WHERE ID = @BatchId
IF @@ROWCOUNT < 1
BEGIN
RAISERROR('header id was not found', 16, 1)
RETURN
END
-- Place Commas for charindex
IF @MyList > ''
SET @MyList = ',' + @MyList + ','
IF @MySICList > ''
SET @MySICList = ',' + @MySICList + ','
IF @MyProvider > ''
SET @MyProvider = ',' + @MyProvider + ','
IF @MyCityList > ''
SET @MyCityList = ',' + @MyCityList + ','
IF @MyZipList > ''
SET @MyZipList = ',' + @MyZipList + ','
--
-- 3. Add qualifying leads.
--
INSERT INTO myschema.Destination
(Id, LeadBatchDetailId, CustomerIdOne, CustomerIdTwo, MyProviderOne, MyProviderTwo, SicCode, SicDesc, SicCode2, SicDesc2,
MyType, Company, CompanyURL, Title, Salutation, Suffix, FullName, FirstName, MiddleInitial,
LastName, Email, MyPhone, Work, Cell, Home, Fax, Ext, Address1, Address2, City, [State],
Zip5, Zip4, County, TSR, EmployeeSize, Revenue, MyProviderOne, MyProviderTwo, CustomerUsageOne, CustomerUsageTwo, MyExpenses, Remarks, Decline,
WhyLeft, PCC, RCC, PCC, SCC)
SELECT
@BatchId, d.ID, d.CustomerIdOne, d.CustomerIdTwo, d.MyProviderOne, d.MyProviderTwo, d.SicCode, d.SicDesc, d.SicCode2, d.SicDesc2,
d.MyType, d.Company, d.CompanyURL, d.Title, d.Salutation, d.Suffix, d.FullName, d.FirstName, d.MiddleInitial,
d.LastName, d.Email, d.MyPhone, d.Work, d.Cell, d.Home, d.Fax, d.Ext, d.Address1, d.Address2, d.City, d.[State],
d.Zip5, d.Zip4, d.County, d.TSR, d.EmployeeSize, d.Revenue, d.MyProviderOne, d.MyProviderTwo,d.CustomerUsageOne, d.CustomerUsageTwo, d.MyExpenses, d.Remarks, d.Decline,
d.WhyLeft, d.PCC, d.RCC, d.PCC, d.SCC
FROM myschema.Source as d
JOIN myschema.Summary as h ON d.MyId = h.ID
JOIN myschema.source AS s ON h.Id = s.ID
WHERE
-- MyId.
(@MyList = '' OR (charindex(',' + CAST(d.MyId AS VARCHAR) + ',', @MyList) > 0)) AND
-- SIC Code.
(@MySICList = '' OR (charindex(',' + CAST(d.SicCode AS VARCHAR) + ',', @MySICList) > 0)) AND
-- My Types
(@MyType = '' OR @MyType = 'A' OR d.MyType = @MyType OR h.DefaultMyType = @MyType) AND
-- MYProviders
((@MyProvider = '' OR (charindex(',' + CAST(d.MyProviderOne AS VARCHAR) + ',', @MyProvider) > 0)) OR
(@MyProvider = '' OR (charindex(',' + CAST(d.MyProviderTwo AS VARCHAR) + ',', @MyProvider) > 0))) AND
-- State.
(@MyState = '' OR d.[State] = @MyState) AND
-- City.
(@MyCityList = '' OR (charindex(',' + d.City + ',', @MyCityList) > 0)) AND
-- Zip Code.
(@MyZipList = '' OR (charindex(',' + d.Zip5 + ',', @MyZipList) > 0)) AND
-- LeadSource
(@MySource = '' OR s.MySource = @MySource) AND
-- Between Dates
(@MyStartDate = '' AND @MyEndDate = '' OR h.CreationDate BETWEEN @MyStartDate AND @MyEndDate) AND
-- Mystyle
((@MyStyle = 'A' AND (d.MyProviderOne IS NOT NULL OR d.MyProviderOne > 0 OR d.CustomerUsageOne > 0)) OR
(@MyStyle = 'B' AND (d.MyProviderTwo IS NOT NULL OR d.MyProviderTwo > 0 OR d.CustomerUsageTwo > 0)) OR
(@MyStyle = '' OR @MyStyle IS NULL)) AND
-- Source parameters are important. Only processed finished batches.
(h.UseThisRecord = 1) AND
(h.[status] = 'Finished') AND
(d.MyDuplicate IS NULL) AND
(d.DoNotUseFlag IS NULL) AND
(d.DoNotUseIFlag IS NULL) AND
(d.CustomerHome IS NULL) AND
(d.CustomerWork IS NULL) AND
(d.LeadDuplicate IS NULL) AND
(d.MyPhone >'' OR d.MyPhone <> NULL) AND
((CAST(FLOOR( CAST( h.ExpirationDate AS FLOAT ) )AS DATETIME) > CAST(FLOOR( CAST( GETDATE() AS FLOAT ) )AS DATETIME)) OR
h.ExpirationDate IS NULL)
--
-- 4. Flag Phone Duplicates inside myschema.Destination
--
UPDATE T1
SET DeleteFlag = 1
FROM myschema.Destination T1, myschema.Destination T2
WHERE
T1.MyPhone = T2.MyPhone AND
T1.FullName = T2.FullName AND
T1.Address1 = T2.Address1 AND
T1.City = T2.City AND
T1.[State] = T2.[State] AND
T1.Zip5 = T2.Zip5 AND
T1.MyPhone <> '' AND
T1.Id = T2.Id AND -- This will flag the batch itself
T1.Id = @BatchId AND
T1.Id < T2.Id -- This will leave the highest Id unflagged (latest record)
--
-- 5. Duplicate Contact Flag. All Records
--
IF @MyCampaign = 1
UPDATE T1
SET DeleteFlag = 1
FROM myschema.Destination T1, myschema.Destination T2
WHERE
T1.MyPhone = T2.MyPhone AND
T1.FullName = T2.FullName AND
T1.Address1 = T2.Address1 AND
T1.City = T2.City AND
T1.[State] = T2.[State] AND
T1.Zip5 = T2.Zip5 AND
T1.MyPhone <> '' AND
T1.Id = @BatchId AND
T1.Id <> T2.Id -- Process against other batches
--
-- 6. Active Flag
--
IF @MyCampaign <> 1
UPDATE T1
SET DeleteFlag = 1
FROM myschema.Destination T1, myschema.Destination T2
JOIN myschema.Header H ON T2.Id = H.ID
WHERE
T1.MyPhone = T2.MyPhone AND
T1.FullName = T2.FullName AND
T1.Address1 = T2.Address1 AND
T1.City = T2.City AND
T1.[State] = T2.[State] AND
T1.Zip5 = T2.Zip5 AND
T1.MyPhone <> '' AND
T1.Id = @BatchId AND
T1.Id <> T2.Id AND -- Process against other batches
H.ActiveBatch = 1 -- Only Active
--
-- 7. Delete DeleteFlag rows. Check for Id just in case
--
IF @BatchId > 0
DELETE FROM myschema.Destination
WHERE
(DeleteFlag = 1) AND (Id = @BatchId)
--
-- 8. Update header with date last run
--
UPDATE myschema.Header
SET DateLastRun = GETDATE()
WHERE ID = @BatchId
END
GO
谢谢, 基督教
答案 0 :(得分:5)
当您在proc和常量ad-hoc
中使用参数时,通常会发生这种情况SQL Server通常会尝试生成可重用的计划。使用常量它不需要,因为它永远不能重复用于不同的常量。
还有其他选项,例如存储过程的SET选项或数据类型不匹配..但我们没有进一步的信息。
答案 1 :(得分:3)
1 - 显示代码。
2 - 没有看到代码,我猜你有多个参数要传递给存储过程,而你有一个parameter sniffing issue.
答案 2 :(得分:2)
这可能是由于参数嗅探造成的。你有没有比较执行计划?如果从http://www.sqlsentry.net/plan-explorer/sql-server-query-view.asp获取免费的计划资源管理器,您可以非常清楚地看到存储过程参数的运行时与编译值。有时在程序中添加WITH RECOMPILE可以帮助防止错误的计划(每次执行程序时可能会略微提高CPU使用率)。但它并不总是最好的答案 - 目前缓存的计划可能是非典型的,每次重建都可能过度。有时答案是如何定义参数 - 例如如果你传递一个参数,你有时可以通过声明一个局部变量并将输入参数传递给它并在代码中稍后使用局部变量来阻止参数嗅探。有时,答案是开启针对临时设置的优化。很难说没有更多细节。
调查计划是一个很好的第一步。如果您发现计划有所不同,请提供差异,我们可以为您提供指导。
答案 3 :(得分:1)
查看sproc和查询会有所帮助,但我猜测存储过程缓存了一些“坏”。尝试清除SQL的缓存(假设您的标记中包含SQL Server)。见this
答案 4 :(得分:1)
存储过程可能存在错误的查询计划。尝试删除并重新创建存储过程。
答案 5 :(得分:0)
可能是你以一种有趣的方式将驱动查询放在循环中 - 使其执行次数太多。
我同意所有其他人 - 显示代码。