SP 在强大的服务器上很慢,但在本地很快(都来自 SSMS)

Posted

技术标签:

【中文标题】SP 在强大的服务器上很慢,但在本地很快(都来自 SSMS)【英文标题】:SP slow on powerful server, but quick locally (both from SSMS) 【发布时间】:2012-09-19 10:07:19 【问题描述】:

我继承了一个大而慢的存储过程,它让我做噩梦:

我的桌面上安装了 SQL Server 2008,并带有生产数据库的副本。我正在运行 SSMS 中的所有内容,并且我尝试过直接的 SQL 和 SP。 Sp vs SQL 的时间已经足够接近了,不必过分担心——我担心的是本地 vs 服务器的时间。

Local:
2Ghz dual-core
4Gb RAM
SQL 2008 Sp1
Microsoft SQL Server 2008 R2 (SP1) - 10.50.2500.0 (Intel X86)   
Enterprise Edition on Windows NT 6.1 <X86> (Build 7601: Service Pack 1) 

Server:
2Ghz dual-core
4Gb RAM
Microsoft SQL Server 2008 (SP1) - 10.0.2573.0 (X64)   
Standard Edition (64-bit) on Windows NT 5.2 <X64> (Build 3790: Service Pack 2) (VM) 

当我“本地”运行存储过程时,大约需要 6 秒才能完成。

当我对服务器运行存储过程时,大约需要 25 分钟才能完成!!!

[总插入次数 = 45,500]

我已尝试尽可能多地调整 SP 并避免参数嗅探,但不确定为什么这在几乎等效的机器上会慢得多(我知道 SQL Server 版本略有不同,但看不到为什么会有这么大的不同?)

我知道 SP 并不出色,但如果它在本地运行 6 秒,那么它不是完全裤子!如果在服务器上花费 60 秒,那仍然可以。有 15 次调用此 SP...所以 15*0:06 可以接受...15*25:00 不可​​以!

当这些 SP 没有运行时,服务器的负载非常低,而当它们在运行时,大约 50% 的 CPU(一个核心 100%?)。本地 CPU 永远不会超过 25%。


Apols 用于发布整个 SP...但是如果有一个可以设置为改进的选项,则看不到如何显示它的作用:(

ALTER PROCEDURE [dbo].[LoadProfitabilitySummaryByCustomer] 
    @inCustomerType char(2),
    @inClearTable int = 0,
    @inStartNum int,
    @inEndNum int
WITH RECOMPILE
AS
    BEGIN
    SET ANSI_NULLS ON
    DECLARE @customers TABLE (
        CUSNUM CHAR(6) DEFAULT 0
        ,IILQAR DECIMAL(20,5) DEFAULT 0
        ,IILUSD DECIMAL(20,5) DEFAULT 0
        ,IILGPB DECIMAL(20,5) DEFAULT 0
        ,IILEUR DECIMAL(20,5) DEFAULT 0
        ,IILKWD DECIMAL(20,5) DEFAULT 0
        ,IILOTH DECIMAL(20,5) DEFAULT 0
        ,IILMTD DECIMAL(20,5) DEFAULT 0
        ,IILYTD DECIMAL(20,5) DEFAULT 0
        ,TCQAR DECIMAL(20,5) DEFAULT 0
        ,TCUSD DECIMAL(20,5) DEFAULT 0
        ,TCGPB DECIMAL(20,5) DEFAULT 0
        ,TCEUR DECIMAL(20,5) DEFAULT 0
        ,TCKWD DECIMAL(20,5) DEFAULT 0
        ,TCOTH DECIMAL(20,5) DEFAULT 0
        ,TCMTD DECIMAL(20,5) DEFAULT 0
        ,TCYTD DECIMAL(20,5) DEFAULT 0
        )

    DECLARE @CustomerType char(2)
    DECLARE @ClearTable int
    DECLARE @StartNum int
    DECLARE @EndNum int

    SET @CustomerType = @inCustomerType
    SET @ClearTable = @inClearTable
    SET @StartNum = @inStartNum
    SET @EndNum = @inEndNum

    DECLARE @sCustomerNumber char(6)

    DECLARE @iDaysInMonth decimal
    DECLARE @iDaysInYear decimal
    DECLARE @dAvgCostQAR DECIMAL(20,5)
    DECLARE @dAvgCostUSD DECIMAL(20,5)
    DECLARE @dAvgCostGBP DECIMAL(20,5)
    DECLARE @dAvgCostEUR DECIMAL(20,5)
    DECLARE @dAvgCostKWD DECIMAL(20,5)
    DECLARE @dAvgCostOTH DECIMAL(20,5)
    DECLARE @dAvgCostTOT DECIMAL(20,5)
    DECLARE @dTIIntIncLnsQAR DECIMAL(20,5)
    DECLARE @dTIIntIncLnsUSD DECIMAL(20,5)
    DECLARE @dTIIntIncLnsGBP DECIMAL(20,5)
    DECLARE @dTIIntIncLnsEUR DECIMAL(20,5)
    DECLARE @dTIIntIncLnsKWD DECIMAL(20,5)
    DECLARE @dTIIntIncLnsOTH DECIMAL(20,5)
    DECLARE @dTIIntIncLnsTOT DECIMAL(20,5)
    DECLARE @dTIIntIncLnsYTD DECIMAL(20,5)
    DECLARE @dTITradeCommQAR DECIMAL(20,5)
    DECLARE @dTITradeCommUSD DECIMAL(20,5)
    DECLARE @dTITradeCommGBP DECIMAL(20,5)
    DECLARE @dTITradeCommEUR DECIMAL(20,5)
    DECLARE @dTITradeCommKWD DECIMAL(20,5)
    DECLARE @dTITradeCommOTH DECIMAL(20,5)
    DECLARE @dTITradeCommTOT DECIMAL(20,5)
    DECLARE @dTITradeCommYTD DECIMAL(20,5)
    DECLARE @dtMaxDate varchar(30)

    DECLARE @iReportYear int
    DECLARE @START_DATE datetime
    DECLARE @FIRST_MONTH datetime
    DECLARE @END_MONTH datetime
    DECLARE @iNumMonths int
    DECLARE @iNumDaysToday int

    INSERT INTO @customers (CUSNUM)
        SELECT DISTINCT CUSNUM
            FROM EQPRF_SUMMARY
            WHERE CUSTYP = @CustomerType
                AND CUSNUM >= @StartNum
                AND CUSNUM < @EndNum
            GROUP BY CUSNUM

    UPDATE @customers
    SET IILQAR = t2.Amount
    FROM @customers c INNER JOIN
        (
            SELECT CUSNUM,
                -SUM(ISNULL(CONVERT(decimal(20,5),t.TOTALMTDLCY),0)) as Amount
            FROM TI_INTINCLOANS t
            WHERE t.CCY = 'IILQAR'
                AND t.LINEID = 'LN17'
            GROUP BY t.CUSNUM
        ) AS t2
        ON c.CUSNUM = t2.CUSNUM

    UPDATE @customers
    SET IILUSD = t2.Amount
    FROM @customers c INNER JOIN
        (
            SELECT CUSNUM,
                -SUM(ISNULL(CONVERT(decimal(20,5),t.TOTALMTDLCY),0)) as Amount
            FROM TI_INTINCLOANS t
            WHERE t.CCY = 'IILUSD'
                AND t.LINEID = 'LN17'
            GROUP BY t.CUSNUM
        ) AS t2
        ON c.CUSNUM = t2.CUSNUM

    --REPEAT FOR 14 OTHER CRITERIA  

    IF (@ClearTable = 1)
        BEGIN
            IF EXISTS (SELECT name FROM sysindexes WHERE name = 'IX_GROUP_ACCT') DROP INDEX IX_GROUP_ACCT ON PROFITABILITY_SUMMARY

            TRUNCATE TABLE [PROFITABILITY_SUMMARY]

            IF NOT EXISTS (SELECT name FROM sysindexes WHERE name = 'IX_GROUP_ACCT')
            CREATE NONCLUSTERED INDEX IX_GROUP_ACCT
            ON dbo.PROFITABILITY_SUMMARY(CUST_TYPE,GROUP_CODE,ACCOUNT)
            WITH (FILLFACTOR = 90,PAD_INDEX = ON);  
        END

    IF MONTH(getdate())= 1 SET @iReportYear = YEAR(DATEADD(m,-1,getdate()))  -- get last month's year
    ELSE SET @iReportYear = YEAR(getdate())

    SET @START_DATE = CAST('1/1/'+cast(@iReportYear as varchar(4)) as datetime) --first day of report year (If Jan, it's last year)
    SET @FIRST_MONTH = DATEADD(day,-DAY(getdate())+1,getdate())--first day of current month
    SET @END_MONTH = DATEADD(day,-1,@FIRST_MONTH)--determine last day of the previous month
    SET @FIRST_MONTH = DATEADD(M,-1,@FIRST_MONTH)--reset to first day of the previous month
    SET @FIRST_MONTH = CAST(FLOOR( CAST( @FIRST_MONTH AS FLOAT ) ) AS DATETIME) --TRUNCATE HOURS
    SET @END_MONTH = CAST(FLOOR( CAST( @END_MONTH AS FLOAT ) ) AS DATETIME) --TRUNCATE HOURS

    SELECT TOP 1 
        @dAvgCostQAR = AVGCOSTQAR
        ,@dAvgCostUSD = AVGCOSTUSD
        ,@dAvgCostGBP = AVGCOSTGBP
        ,@dAvgCostEUR = AVGCOSTEUR
        ,@dAvgCostKWD = AVGCOSTKWD
        ,@dAvgCostOTH = AVGCOSTOTH
        ,@dAvgCostTOT = AVGCOSTTOT
    FROM dbo.PRFCOSTF

    SET @dtMaxDate = (select top 1 s.txnstmp from EQPRF_SUMMARY s)
    SELECT @iDaysInMonth = dbo.ufn_GetDaysInMonth(CAST(@dtMaxDate as datetime))
    SELECT @iDaysInYear = 360
    SET @iNumDaysToday = (DATEDIFF(dd, @START_DATE, @END_MONTH)+1)

    DECLARE CustomerCursor CURSOR FAST_FORWARD
        FOR
        SELECT CUSNUM
        FROM @customers

    OPEN CustomerCursor

    FETCH NEXT FROM CustomerCursor 
        INTO @sCustomerNumber

    WHILE @@FETCH_STATUS = 0
        BEGIN

        SELECT 
            @dTIIntIncLnsQAR = c.IILQAR
            ,@dTIIntIncLnsUSD = c.IILUSD
            ,@dTIIntIncLnsGBP = c.IILGPB
            ,@dTIIntIncLnsEUR = c.IILEUR
            ,@dTIIntIncLnsKWD = c.IILKWD
            ,@dTIIntIncLnsOTH = c.IILOTH
            ,@dTIIntIncLnsTOT = c.IILMTD
            ,@dTIIntIncLnsYTD = c.IILYTD
            ,@dTITradeCommQAR = c.TCQAR
            ,@dTITradeCommUSD = c.TCUSD
            ,@dTITradeCommGBP = c.TCGPB
            ,@dTITradeCommEUR = c.TCEUR
            ,@dTITradeCommKWD = c.TCKWD
            ,@dTITradeCommOTH = c.TCOTH
            ,@dTITradeCommTOT = c.TCMTD
            ,@dTITradeCommYTD = c.TCYTD
        FROM @customers c
        WHERE c.CUSNUM = @sCustomerNumber

    INSERT INTO PROFITABILITY_SUMMARY
            SELECT SORT_ORDER = 1, LINE_NO = 'LN01', RPT_DATE=cast(TXNSTMP as datetime),
                LINE_TITLE='Month Loans Outstanding', 
                ACCOUNT = RTRIM(CUSNUM),
                CUST_TYPE = RTRIM(CUSTYP),
                GROUP_CODE = (CASE
                                WHEN RTRIM(CUSGRP) IS NULL OR RTRIM(CUSGRP)='' THEN LEFT(CUSNAME,3)+'--'+RTRIM(CUSNUM)
                                ELSE RTRIM(CUSGRP)
                                END),
                PARENT_COUNTRY = RTRIM(CUSNAP),
                RM_CODE = RTRIM(CUSACO),
                RM_NAME = RTRIM(CUSRNAM),
                CUST_NAME = RTRIM(CUSNAME),
                RISK_CODE = RTRIM(CUSRSKE),
                QAR = ISNULL((SELECT CAST(CURDLAMT AS DECIMAL(20,5)) FROM [MISReportInterface].[dbo].[EQPRF_SUMMARY]
              where CUSNUM=@sCustomerNumber AND CUSCCY='QAR'),0),
                USD = ISNULL((SELECT CAST(CURDLAMT AS DECIMAL(20,5)) FROM [MISReportInterface].[dbo].[EQPRF_SUMMARY]
              where CUSNUM=@sCustomerNumber AND CUSCCY='USD'),0),
                GBP = ISNULL((SELECT CAST(CURDLAMT AS DECIMAL(20,5)) FROM [MISReportInterface].[dbo].[EQPRF_SUMMARY]
              where CUSNUM=@sCustomerNumber AND CUSCCY='GBP'),0),
                EUR = ISNULL((SELECT CAST(CURDLAMT AS DECIMAL(20,5)) FROM [MISReportInterface].[dbo].[EQPRF_SUMMARY]
              where CUSNUM=@sCustomerNumber AND CUSCCY='EUR'),0),
                KWD = ISNULL((SELECT CAST(CURDLAMT AS DECIMAL(20,5)) FROM [MISReportInterface].[dbo].[EQPRF_SUMMARY]
              where CUSNUM=@sCustomerNumber AND CUSCCY='KWD'),0),
                OTHER = ISNULL((SELECT sum(CAST(CURDLAMT AS DECIMAL(20,5))) FROM [MISReportInterface].[dbo].[EQPRF_SUMMARY]
              where CUSNUM=@sCustomerNumber AND CUSCCY NOT IN ('QAR', 'USD', 'GBP', 'EUR', 'KWD')),0),
                TOTAL = SUM(CAST(CURDLAMT AS DECIMAL(20,5))),
                YTD = 0
              FROM [MISReportInterface].[dbo].[EQPRF_SUMMARY] where CUSNUM=@sCustomerNumber
              GROUP BY CUSNUM,CUSTYP,CUSGRP,CUSNAP,CUSACO,CUSRNAM,CUSNAME,CUSRSKE,TXNSTMP

            UNION ALL
                SELECT SORT_ORDER = 2,LINE_NO = 'LN02', RPT_DATE=cast(TXNSTMP as datetime),
                    LINE_TITLE ='Average Loans Outstanding', 
                    ACCOUNT = RTRIM(CUSNUM),
                    CUST_TYPE = RTRIM(CUSTYP),
                GROUP_CODE = (CASE
                                WHEN RTRIM(CUSGRP) IS NULL OR RTRIM(CUSGRP)='' THEN LEFT(CUSNAME,3)+'--'+RTRIM(CUSNUM)
                                ELSE RTRIM(CUSGRP)
                                END),
                    PARENT_COUNTRY = RTRIM(CUSNAP),
                    RM_CODE = RTRIM(CUSACO),
                    RM_NAME = RTRIM(CUSRNAM),
                    CUST_NAME = RTRIM(CUSNAME),
                    RISK_CODE = RTRIM(CUSRSKE),
                    QAR = ISNULL((SELECT CAST(LNAVGMTD AS DECIMAL(20,5)) FROM [MISReportInterface].[dbo].[EQPRF_SUMMARY]
                  where CUSNUM=@sCustomerNumber AND CUSCCY='QAR'),0),
                    USD = ISNULL((SELECT CAST(LNAVGMTD AS DECIMAL(20,5)) FROM [MISReportInterface].[dbo].[EQPRF_SUMMARY]
                  where CUSNUM=@sCustomerNumber AND CUSCCY='USD'),0),
                    GBP = ISNULL((SELECT CAST(LNAVGMTD AS DECIMAL(20,5)) FROM [MISReportInterface].[dbo].[EQPRF_SUMMARY]
                  where CUSNUM=@sCustomerNumber AND CUSCCY='GBP'),0),
                    EUR = ISNULL((SELECT CAST(LNAVGMTD AS DECIMAL(20,5)) FROM [MISReportInterface].[dbo].[EQPRF_SUMMARY]
                  where CUSNUM=@sCustomerNumber AND CUSCCY='EUR'),0),
                    KWD = ISNULL((SELECT CAST(LNAVGMTD AS DECIMAL(20,5)) FROM [MISReportInterface].[dbo].[EQPRF_SUMMARY]
                  where CUSNUM=@sCustomerNumber AND CUSCCY='KWD'),0),
                    OTHER = ISNULL((SELECT SUM(CAST(LNAVGMTD AS DECIMAL(20,5))) FROM [MISReportInterface].[dbo].[EQPRF_SUMMARY]
                  where CUSNUM=@sCustomerNumber AND CUSCCY NOT IN ('QAR', 'USD', 'GBP', 'EUR', 'KWD')),0),
                    TOTAL = SUM(CAST(LNAVGMTD AS DECIMAL(20,5))),
                    YTD = SUM(CAST(LNAVGYTD AS DECIMAL(20,5)))
                  FROM [MISReportInterface].[dbo].[EQPRF_SUMMARY] where CUSNUM=@sCustomerNumber
                  GROUP BY CUSNUM,CUSTYP,CUSGRP,CUSNAP,CUSACO,CUSRNAM,CUSNAME,CUSRSKE,TXNSTMP
------------------------------------------------------------------------------
            --THERE ARE 32 LINES IN TOTAL...ALL FOLLOWING ROUGHLY SAME PATTERN
------------------------------------------------------------------------------
            UNION ALL
                SELECT SORT_ORDER = 32,LINE_NO = 'GRANTOTAL',RPT_DATE=cast(TXNSTMP as datetime),
                    LINE_TITLE ='Total Income', 
                    ACCOUNT = RTRIM(CUSNUM),
                    CUST_TYPE = RTRIM(CUSTYP),
                GROUP_CODE = (CASE
                                WHEN RTRIM(CUSGRP) IS NULL OR RTRIM(CUSGRP)='' THEN LEFT(CUSNAME,3)+'--'+RTRIM(CUSNUM)
                                ELSE RTRIM(CUSGRP)
                                END),
                    PARENT_COUNTRY = RTRIM(CUSNAP),
                    RM_CODE = RTRIM(CUSACO),
                    RM_NAME = RTRIM(CUSRNAM),
                    CUST_NAME = RTRIM(CUSNAME),
                    RISK_CODE = RTRIM(CUSRSKE),
                    QAR = @dTITradeCommQAR+@dTIIntIncLnsQAR+ISNULL((SELECT CAST(SUSINTMTD AS DECIMAL(20,5)) + CAST(INTINCMTD AS DECIMAL(20,5))- cast(COSTLNMTD as DECIMAL(20,5))+cast(COSTDPMTD as DECIMAL(20,5)) - CAST(INTEXPMTD AS DECIMAL(20,5))+CAST(LNFEEMTD  AS DECIMAL(20,5))+CAST(OTRINCMTD  AS DECIMAL(20,5))+CAST(EXCHINCMTD  AS DECIMAL(20,5)) FROM [MISReportInterface].[dbo].[EQPRF_SUMMARY]
                  where CUSNUM=@sCustomerNumber AND CUSCCY='QAR'),0),
                    USD = @dTITradeCommUSD+@dTIIntIncLnsUSD+ISNULL((SELECT CAST(SUSINTMTD AS DECIMAL(20,5)) + CAST(INTINCMTD AS DECIMAL(20,5))- cast(COSTLNMTD as DECIMAL(20,5))+cast(COSTDPMTD as DECIMAL(20,5)) - CAST(INTEXPMTD AS DECIMAL(20,5))+CAST(LNFEEMTD  AS DECIMAL(20,5))+CAST(OTRINCMTD  AS DECIMAL(20,5))+CAST(EXCHINCMTD  AS DECIMAL(20,5)) FROM [MISReportInterface].[dbo].[EQPRF_SUMMARY]
                  where CUSNUM=@sCustomerNumber AND CUSCCY='USD'),0),
                    GBP = @dTITradeCommGBP+@dTIIntIncLnsGBP+ISNULL((SELECT CAST(SUSINTMTD AS DECIMAL(20,5)) + CAST(INTINCMTD AS DECIMAL(20,5))- cast(COSTLNMTD as DECIMAL(20,5))+cast(COSTDPMTD as DECIMAL(20,5)) - CAST(INTEXPMTD AS DECIMAL(20,5))+CAST(LNFEEMTD  AS DECIMAL(20,5))+CAST(OTRINCMTD  AS DECIMAL(20,5))+CAST(EXCHINCMTD  AS DECIMAL(20,5)) FROM [MISReportInterface].[dbo].[EQPRF_SUMMARY]
                  where CUSNUM=@sCustomerNumber AND CUSCCY='GBP'),0),
                    EUR = @dTITradeCommEUR+@dTIIntIncLnsEUR+ISNULL((SELECT CAST(SUSINTMTD AS DECIMAL(20,5)) + CAST(INTINCMTD AS DECIMAL(20,5))- cast(COSTLNMTD as DECIMAL(20,5))+cast(COSTDPMTD as DECIMAL(20,5)) - CAST(INTEXPMTD AS DECIMAL(20,5))+CAST(LNFEEMTD  AS DECIMAL(20,5))+CAST(OTRINCMTD  AS DECIMAL(20,5))+CAST(EXCHINCMTD  AS DECIMAL(20,5)) FROM [MISReportInterface].[dbo].[EQPRF_SUMMARY]
                  where CUSNUM=@sCustomerNumber AND CUSCCY='EUR'),0),
                    KWD = @dTITradeCommKWD+@dTIIntIncLnsKWD+ISNULL((SELECT CAST(SUSINTMTD AS DECIMAL(20,5)) + CAST(INTINCMTD AS DECIMAL(20,5))- cast(COSTLNMTD as DECIMAL(20,5))+cast(COSTDPMTD as DECIMAL(20,5)) - CAST(INTEXPMTD AS DECIMAL(20,5))+CAST(LNFEEMTD  AS DECIMAL(20,5))+CAST(OTRINCMTD  AS DECIMAL(20,5))+CAST(EXCHINCMTD  AS DECIMAL(20,5)) FROM [MISReportInterface].[dbo].[EQPRF_SUMMARY]
                  where CUSNUM=@sCustomerNumber AND CUSCCY='KWD'),0),
                    OTHER=@dTITradeCommOTH+@dTIIntIncLnsOTH+ISNULL((SELECT SUM(CAST(SUSINTMTD AS DECIMAL(20,5)))+ SUM(CAST(INTINCMTD AS DECIMAL(20,5)))-SUM(CAST(COSTLNMTD AS DECIMAL(20,5)))+SUM(CAST(COSTDPMTD AS DECIMAL(20,5))) - SUM(CAST(INTEXPMTD AS DECIMAL(20,5)))+SUM(CAST(LNFEEMTD AS DECIMAL(20,5)))+SUM(CAST(OTRINCMTD  AS DECIMAL(20,5)))+SUM(CAST(EXCHINCMTD  AS DECIMAL(20,5))) FROM [MISReportInterface].[dbo].[EQPRF_SUMMARY]
                  where CUSNUM=@sCustomerNumber AND CUSCCY NOT IN ('QAR', 'USD', 'GBP', 'EUR', 'KWD')),0),
                    TOTAL = @dTITradeCommTOT+@dTIIntIncLnsTOT+ SUM(CAST(SUSINTMTD AS DECIMAL(20,5)))+SUM(CAST(INTINCMTD AS DECIMAL(20,5)))-SUM(CAST(COSTLNMTD AS DECIMAL(20,5)))+SUM(cast(COSTDPMTD as DECIMAL(20,5))) - SUM(CAST(INTEXPMTD AS DECIMAL(20,5)))+SUM(CAST(LNFEEMTD  AS DECIMAL(20,5)))+SUM(CAST(OTRINCMTD  AS DECIMAL(20,5)))+SUM(CAST(EXCHINCMTD  AS DECIMAL(20,5))),
                    YTD = @dTITradeCommYTD+@dTIIntIncLnsYTD+ SUM(CAST(SUSINTYTD AS DECIMAL(20,5)))+SUM(CAST(INTINCYTD AS DECIMAL(20,5)))-SUM(CAST(COSTLNYTD AS DECIMAL(20,5)))+SUM(cast(COSTDPYTD as DECIMAL(20,5))) - SUM(CAST(INTEXPYTD AS DECIMAL(20,5)))+SUM(CAST(LNFEEYTD  AS DECIMAL(20,5)))+SUM(CAST(OTRINCYTD  AS DECIMAL(20,5)))+SUM(CAST(EXCHINCYTD  AS DECIMAL(20,5)))

                  FROM [MISReportInterface].[dbo].[EQPRF_SUMMARY] where CUSNUM=@sCustomerNumber
                GROUP BY CUSNUM,CUSTYP,CUSGRP,CUSNAP,CUSACO,CUSRNAM,CUSNAME,CUSRSKE,TXNSTMP
            ORDER BY 1

        FETCH NEXT 
            FROM CustomerCursor 
            INTO @sCustomerNumber

        END

    CLOSE CustomerCursor
    DEALLOCATE CustomerCursor

END

【问题讨论】:

为什么这被标记为关闭?这是一个合理的问题:为什么 SP 在服务器上的运行速度会比本地慢得多?如果有原因(代码太长?),请发表评论,我会相应地进行编辑。 相同的数据库(表中的数据相同)? 虚拟机是(VM)吗? 是的,相同的数据库(生产副本)和虚拟机上的产品。 插入 db 可能会导致磁盘写入负载过高。通过他们的(不是专家)“虚拟磁盘接口”,VM 并不是真正适合在硬件上进行高负载写入。当性能成为问题时,我总是选择不虚拟化 SQL Server。 【参考方案1】:

桌面无负载,服务器负载低。方式不同。如果您想要公平比较,请关闭用户并将两个数据库置于单用户模式。

这些插入需要获取锁。即使是低负载也可能持有很多锁。

另一个需要注意的是索引碎片,但我敢打赌它可以用锁来解释。

如果您有活动用户使用共享锁,他们不会互相阻止。

但是共享锁会阻止 SP 获取更新锁。

脏读(无锁)不会阻塞更新锁。

启动用户并进行测试。如果时间减少,那么很可能是锁定问题。

【讨论】:

谢谢,但试过了。没有用户(除了我)并且表格对用户来说是只读的(它用于报告 - 所以他们只能通过 s-s-rS 访问......我停止了测试) 如您所料,Profiler 显示为插入获取/释放了很多锁...有没有其他方法可以做到这一点。例如批量插入,以便将它们全部放在一个“锁定”下? 如果它是一个只读表,那么你如何插入记录。我解释了一个共享锁,你的回答是“无论如何都是只读的”。 "对用户只读"...即他们无法执行插入。这并没有向我解释共享锁,它只是告诉我我可能拥有它们。【参考方案2】:

答案:VM Ware 导致磁盘写入速度非常慢。

物理服务器上的相同数据库非常快。 VM 服务器上的同一个数据库又变慢了。

【讨论】:

以上是关于SP 在强大的服务器上很慢,但在本地很快(都来自 SSMS)的主要内容,如果未能解决你的问题,请参考以下文章

SQL View 在管理控制台中速度很慢,但在 App 层中速度很快

Highcharts 鼠标跟踪/鼠标悬停功能在 chrome 上很慢,但在 Firefox 或 IE 上并不慢

asp.net网站外网访问突然变慢,服务器本地访问很快,怎么办?

为啥完全相同的查询在 prod env 中很快,但在 Dev env 中却很慢?

大结果在任何地方都很慢,但在本地

SQL 查询在 SQL Server CE 中很慢,但在 SQL Server 中很快