我有一个存储过程虽然工作正常,但使用了大量临时表,因此性能下降。是否有可能改进/重写它(可能使用CTE或其他方式来提高性能)
CREATE PROCEDURE [dbo].[PORT_GetFutureOpportunities]
-- Add the parameters for the stored procedure here
(
@SiebelAccId VARCHAR(50),
@FromDate DATETIME,
@ToDate DATETIME,
@FilterCriteria INT,
@AutoRenewalChk INT
)
AS
BEGIN
DECLARE @FDate DATETIME, @TDate DATETIME
SET @FDate = DATEADD(day, DATEDIFF(day, 0, @FromDate), 0)
SET @TDate = DATEADD(day, DATEDIFF(day, 0, @ToDate), 0)
SELECT DISTINCT e.nai_grant_number
INTO #temp
FROM smbecommerce..SalesItem si
INNER JOIN smbecommerce..sales s ON s.sales_id = si.sales_id
INNER JOIN siebelextract..entitlement e ON SUBSTRING(e.nai_grant_number, 1, NULLIF(CHARINDEX('-', e.nai_grant_number) - 1, -1)) = CAST (s.sales_order_id AS VARCHAR)
WHERE si.auto_renewal_flag = (CASE WHEN @AutoRenewalChk = 1 THEN 1 END )
OR si.auto_renewal_flag <= ( CASE WHEN @AutoRenewalChk = 0 THEN 1 END)
--Creating Main query
SELECT
e.nai_agreement_account_name AS [CompanyName]
,c.first_name + ' ' + c.last_name AS [ContactName]
,c.work_phone AS [ContactPhone]
,c.email_address AS [EmailAddress]
,e.entitlement_end_date AS [ExpirationDate]
,e.nai_grant_number AS [GrantNumber]
,e.nai_quantity AS [Quantity]
,e.product_name AS [SkuDescription]
,(CASE WHEN LEN(e.nai_superceded_id) > 0 THEN 1 ELSE 0 END) AS [IsRenewed]
INTO #temp1
FROM siebelextract..entitlement e
INNER JOIN siebelextract..account a ON a.row_id = e.nai_reseller_id
INNER JOIN SiebelExtract.[dbo].contact c WITH (NOLOCK) ON e.nai_primary_contact_id = c.row_id
WHERE a.parent_account_id = @SiebelAccId
AND LEN(E.nai_reason_code) = 0
AND EXISTS (SELECT 1 FROM smbecommerce..renewalskus rs WHERE RS.sku = E.product_name)
AND e.entitlement_end_date
BETWEEN @FDate
AND @TDate
IF (@AutoRenewalChk = 0 OR @AutoRenewalChk = 1)
BEGIN
CREATE TABLE #temp2(
CompanyName VARCHAR(200)
,ContactName VARCHAR(200)
,ContactPhone VARCHAR(200)
,EmailAddress VARCHAR(200)
,ExpirationDate DATETIME
,GrantNumber VARCHAR(200)
,Quantity INT
,SkuDescription VARCHAR(200)
,IsRenewed INT
)
IF @AutoRenewalChk = 0
BEGIN
INSERT INTO #temp2 select #temp1.* FROM #temp1
END
IF @AutoRenewalChk = 1
BEGIN
INSERT INTO #temp2 SELECT * FROM #temp1 WHERE #temp1.[GrantNumber] NOT IN(SELECT t1.nai_grant_number FROM #temp t1)
END
END
IF @FilterCriteria = 0
BEGIN
SELECT te.[CompanyName],te.[ContactName],te.[EmailAddress],te.[ContactPhone],te.[SkuDescription],te.[Quantity],te.[GrantNumber],te.[ExpirationDate],te.[IsRenewed] FROM #temp2 te
END
IF @FilterCriteria = 1
BEGIN
SELECT te.[CompanyName],te.[ContactName],te.[EmailAddress],te.[ContactPhone],te.[SkuDescription],te.[Quantity],te.[GrantNumber],te.[ExpirationDate],te.[IsRenewed] FROM #temp2 te
WHERE te.[IsRenewed] > 0
END
IF @FilterCriteria = 2
BEGIN
SELECT te.[CompanyName],te.[ContactName],te.[EmailAddress],te.[ContactPhone],te.[SkuDescription],te.[Quantity],te.[GrantNumber],te.[ExpirationDate],te.[IsRenewed] FROM #temp2 te
WHERE te.[IsRenewed] = 0
END
DROP TABLE #temp2
DROP TABLE #temp1
DROP TABLE #temp
END
GO
由于
答案 0 :(得分:1)
答案 1 :(得分:1)
我已经压缩了你的存储过程。当然,我没有你的数据库所以我的SSMS看起来像血河之战,但根据你提供的代码,这应该工作。看看,请以任何方式告诉我。
我先粘贴代码,然后解释一下我做了什么。
CREATE PROCEDURE dbo.PORT_GetFutureOpportunities (
@SiebelAccId VARCHAR(50),
@FromDate DATETIME,
@ToDate DATETIME,
@FilterCriteria INT,
@AutoRenewalChk INT
)
AS
BEGIN
DECLARE @FDate DATETIME, @TDate DATETIME
SET @FDate = CAST(@FromDate AS DATE)
SET @TDate = CAST(@ToDate AS DATE)
CREATE TABLE #temp(
CompanyName VARCHAR(200),
ContactName VARCHAR(200),
ContactPhone VARCHAR(200),
EmailAddress VARCHAR(200),
ExpirationDate DATETIME,
GrantNumber VARCHAR(200),
Quantity INT,
SkuDescription VARCHAR(200),
IsRenewed INT
)
WITH cte AS (SELECT DISTINCT e.nai_grant_number FROM smbecommerce..SalesItem si
INNER JOIN smbecommerce..sales s ON s.sales_id = si.sales_id
INNER JOIN siebelextract..entitlement e ON SUBSTRING(e.nai_grant_number, 1, NULLIF(CHARINDEX('-', e.nai_grant_number) - 1, -1)) = CAST (s.sales_order_id AS VARCHAR)
WHERE si.auto_renewal_flag = (CASE WHEN @AutoRenewalChk = 1 THEN 1 END)
OR si.auto_renewal_flag <= (CASE WHEN @AutoRenewalChk = 0 THEN 1 END)),
rs AS (SELECT DISTINCT sku FROM smbecommerce..renewalskus)
INSERT INTO #temp
SELECT e.nai_agreement_account_name, c.first_name + ' ' + c.last_name, c.work_phone, c.email_address, e.entitlement_end_date,
e.nai_grant_number, e.nai_quantity, e.product_name, (CASE WHEN LEN(e.nai_superceded_id) > 0 THEN 1 ELSE 0 END)
FROM siebelextract..entitlement e
INNER JOIN siebelextract..account a ON a.row_id = e.nai_reseller_id
INNER JOIN SiebelExtract.dbo.contact c WITH (NOLOCK) ON e.nai_primary_contact_id = c.row_id
INNER JOIN rs ON rs.sku = e.product_name
LEFT JOIN cte ON e.nai_grant_number = cte.nai_grant_number
WHERE a.parent_account_id = @SiebelAccId
AND LEN(E.nai_reason_code) = 0
AND e.entitlement_end_date BETWEEN @FDate AND @TDate
AND (@AutoRenewalChk = 0 OR cte.nai_grant_number IS NOT NULL)
SELECT CompanyName, ContactName, EmailAddress, ContactPhone, SkuDescription, Quantity, GrantNumber, ExpirationDate, IsRenewed
FROM #temp
WHERE (@FilterCriteria = 0)
OR IsRenewed = (1 - (@FilterCriteria -1))
DROP TABLE #temp
END
IF (@AutoRenewalChk = 0 OR @AutoRenewalChk = 1)
块已被查询中的两行替换:左边连接cte,插入语句的最后一行。事实上,由于我们在这里所做的就是将数据插入到表中然后选择它,我们可以将其进一步压缩到单个select语句中:
CREATE PROCEDURE dbo.PORT_GetFutureOpportunities (
@SiebelAccId VARCHAR(50),
@FromDate DATETIME,
@ToDate DATETIME,
@FilterCriteria INT,
@AutoRenewalChk INT
)
AS
BEGIN
DECLARE @FDate DATETIME, @TDate DATETIME
SET @FDate = CAST(@FromDate AS DATE)
SET @TDate = CAST(@ToDate AS DATE)
WITH cte AS (SELECT DISTINCT e.nai_grant_number FROM smbecommerce..SalesItem si
INNER JOIN smbecommerce..sales s ON s.sales_id = si.sales_id
INNER JOIN siebelextract..entitlement e ON SUBSTRING(e.nai_grant_number, 1, NULLIF(CHARINDEX('-', e.nai_grant_number) - 1, -1)) = CAST (s.sales_order_id AS VARCHAR)
WHERE si.auto_renewal_flag = (CASE WHEN @AutoRenewalChk = 1 THEN 1 END)
OR si.auto_renewal_flag <= (CASE WHEN @AutoRenewalChk = 0 THEN 1 END)),
rs AS (SELECT DISTINCT sku FROM smbecommerce..renewalskus)
SELECT e.nai_agreement_account_name AS [CompanyName], c.first_name + ' ' + c.last_name AS [ContactName],
c.work_phone AS [ContactPhone], c.email_address AS [EmailAddress], e.entitlement_end_date AS [ExpirationDate],
e.nai_grant_number AS [GrantNumber], e.nai_quantity AS [Quantity], e.product_name AS [SkuDescription],
(CASE WHEN LEN(e.nai_superceded_id) > 0 THEN 1 ELSE 0 END) AS [IsRenewed]
FROM siebelextract..entitlement e
INNER JOIN siebelextract..account a ON a.row_id = e.nai_reseller_id
INNER JOIN SiebelExtract.dbo.contact c WITH (NOLOCK) ON e.nai_primary_contact_id = c.row_id
INNER JOIN rs ON rs.sku = e.product_name
LEFT JOIN cte ON e.nai_grant_number = cte.nai_grant_number
WHERE a.parent_account_id = @SiebelAccId
AND LEN(E.nai_reason_code) = 0
AND e.entitlement_end_date BETWEEN @FDate AND @TDate
AND (@AutoRenewalChk = 0 OR cte.nai_grant_number IS NOT NULL)
AND ((@FilterCriteria = 0) OR CASE WHEN LEN(e.nai_superceded_id) > 0 THEN 1 ELSE 0 END = (1 - (@FilterCriteria -1)))
END