Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何提高此存储过程的性能?_Sql_Sql Server_Performance_Tsql_Stored Procedures - Fatal编程技术网

Sql 如何提高此存储过程的性能?

Sql 如何提高此存储过程的性能?,sql,sql-server,performance,tsql,stored-procedures,Sql,Sql Server,Performance,Tsql,Stored Procedures,好的,我对我们已有的存储过程做了一些更改,现在运行它需要3个小时(以前只需要10分钟)。我有一个名为#tCustomersEmail的临时表。其中有一个名为OrderDate的列,其中有许多空值。我想用来自不同服务器上另一个数据库的数据替换这些空值。这就是我所拥有的: 我创建另一个临时表: Create Table #tSouth ( CustID char(10), InvcDate nchar(10) ) 我用这些数据填充这些数据: INSERT INTO #tSouth(CustID,

好的,我对我们已有的存储过程做了一些更改,现在运行它需要3个小时(以前只需要10分钟)。我有一个名为
#tCustomersEmail
的临时表。其中有一个名为
OrderDate
的列,其中有许多空值。我想用来自不同服务器上另一个数据库的数据替换这些空值。这就是我所拥有的:

我创建另一个临时表:

Create Table #tSouth
(
CustID char(10),
InvcDate nchar(10)
)
我用这些数据填充这些数据:

INSERT INTO #tSouth(CustID, InvcDate)
SELECT DISTINCT
      [CustID],
      max(InvcDate) as InvcDate
  FROM D3.SouthW.dbo.uc_InvoiceLine I
  where EXISTS (SELECT CustomerNumber FROM #tCustomersEmail H WHERE   I.CustID =  H.CustomerNumber) 
  group BY I.CustID
然后,我从
#tSouth
获取数据,并更新
#tCustomersEmail
表中的
OrderDate
,只要
CustomerNumber
匹配,并且
OrderDate
为空:

UPDATE #tCustomersEmail  
SET OrderDate = InvcDate 
FROM #tCustomersEmail  
INNER JOIN #tSouth ON #tCustomersEmail.CustomerNumber = [#tSouth].CustID
where #tCustomersEmail.OrderDate IS null
进行这些更改导致存储过程采用FOR-EV-ER(Sandlot reference!)

那么我做错了什么

顺便说一句,在创建临时表之后,我会在临时表上创建索引,如下所示:

create clustered index idx_Customers ON #tCustomersEmail(CustomerNumber)
CREATE clustered index idx_CustSouthW ON #tSouth(CustID)

如果您有一个GROUP BY,则不需要Distinct。考虑到你正在浏览数据库,我不喜欢这个数据库。我将更改该部分以限制该点的行数。改为:

INSERT INTO #tSouth(CustID, InvcDate)
SELECT 
      [CustID],
      max(InvcDate) as InvcDate
  FROM D3.SouthW.dbo.uc_InvoiceLine I
  where I.CustID in 
       (SELECT CustomerNumber 
        FROM #tCustomersEmail H 
        WHERE H.OrderDate IS null ) 
  group BY I.CustID
编辑:仔细看你确定应该使用uc\U发票行吗?看起来应该有一个具有日期且行数较少的父表。 此外,您还可以通过直接执行更新跳过一个临时表:

UPDATE #tCustomersEmail  
SET OrderDate = InvcDate 
FROM #tCustomersEmail  
INNER JOIN (SELECT 
      [CustID],
      max(InvcDate) as InvcDate
  FROM D3.SouthW.dbo.uc_InvoiceLine I
  where I.CustID in 
       (SELECT CustomerNumber 
        FROM #tCustomersEmail H 
        WHERE H.OrderDate IS null ) 
  group BY I.CustID) Invoices
ON #tCustomersEmail.CustomerNumber = Invoices.CustID
尝试跳过#tsouth表并使用此查询:

UPDATE a
SET OrderDate = (select max(InvcDate) from D3.SouthW.dbo.uc_InvoiceLine I 
                 where a.customernumber = custid)  
FROM #tCustomersEmail a  
WHERE orderdate is null

我认为索引在本例中对您没有帮助

很难预测涉及链接服务器上表的复杂查询的行为,因为本地服务器无法访问远程表的统计信息,由于这个原因,最终可能会得到一个糟糕的查询计划——它将在假设远程表有1行或100行的情况下工作。 如果这还不够糟糕,那么糟糕计划的结果可能是将整个远程表通过导线拉入本地临时空间,并在那里工作。如果远程表非常大,这可能是一个主要的性能开销

在中,可能值得尝试简化链接的服务器查询,以最大限度地减少通过连线返回整个表的机会(如前所述,您不需要同时使用
DISTINCT
GROUP BY

保留查询的其余部分不变


但是,由于聚合,这可能仍然会将整个表带回本地服务器-您需要进行测试才能找到答案。如果您能够在SouthW数据库中创建对象,那么最好将此逻辑封装在视图中,然后从SP代码中引用它。

是否可以使用table variable而不是temp table

declare @temp table
(
    CustID char(10),
    InvcDate nchar(10)
)

insert into @temp
...

这肯定会提高性能

为什么所有的临时表?如果您过度使用这些,您的tempdb将出现瓶颈。因为我无法在实际表上放置索引。您是否在存储过程中创建temp表??这可能会导致过程被重新编译多次……是的,我正在SP中创建临时表。D3.SouthW.dbo.uc_InvoiceLine.CustID上是否有索引?uc_InvoiceLine行就是我需要从中获取信息的表。它是一个非规范化的数据库。我忘了提到这一点。我创建#tSouth的原因是,因为没有主键,所以我可以在它上面放一个索引。您的更新方式是否更快?不确定您正在谈论的行数。我喜欢OrderDate现在在从另一个DB返回行之前应用-我认为这将纠正您的性能问题。我正在处理每个表中的数百万行。是的,我仍在等待它运行。40分钟。如果它不超过一个小时,我会很高兴。我会接受这个答案作为解决方案,因为它花费的时间最少。
declare @temp table
(
    CustID char(10),
    InvcDate nchar(10)
)

insert into @temp
...