首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >提高查询速度

提高查询速度
EN

Stack Overflow用户
提问于 2012-03-29 17:10:59
回答 3查看 256关注 0票数 1

使用SQL、SQL server manager 2008、c-sharp.net 4.0和ms visual studio professional 2010:

我一直在为我的程序编写一个主查询,到目前为止,它完全按照预期工作。唯一的问题是运行所需的时间。

有时,大约2000条记录最多需要3分钟。

我被要求更快地获得这个查询,但老实说,我不确定如何才能做到这一点。

查询如下,它使用一个链接服务器和4个表。3在一台服务器上,另一台在本地。

代码语言:javascript
运行
复制
USE [ShaftData]
GO
/****** Object:  StoredProcedure [dbo].[GetSalesBuyers]    Script Date: 03/29/2012   10:03:27 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[GetSalesBuyers] 
@Acct varchar(255),
@Cdisc varchar(255),
@bcs varchar(255), 
@From date, 
@Too date
AS
SELECT i.Acct,
   i.Name, 
   i.Document, 
   i.Part, 
   i.Qty, 
   i.Unit, 
   dbo.NEWPareto.Pareto, 
   i.pg,
   dbo.MyPgTable.PgName,
   i.[DateTime],
   i.BinSeqNo,
   i.cdisc,
   i.bcs

FROM   
OPENQUERY(SACBAUTO, 'SELECT dbo.iHeads.acct,
                            dbo.iHeads.name,
                            dbo.iLines.Document,
                            dbo.iLines.Part,
                            dbo.iLines.Pg,
                            dbo.iLines.Qty,
                            dbo.iLines.unit,
                            dbo.iHeads.[DateTime], 
                            dbo.iLines.BinSeqNo, 
                            dbo.Customer.cdisc,
                            dbo.Customer.Bcs
                     FROM Autopart.dbo.iheads INNER JOIN  Autopart.dbo.iLines ON 
                     Autopart.dbo.Iheads.document = autopart.dbo.iLines.document
                     INNER JOIN Autopart.dbo.Customer ON Autopart.dbo.iheads.acct 
                     = Autopart.dbo.customer.keycode
                     GROUP By dbo.iHeads.acct,
                            dbo.iHeads.name,
                            dbo.iLines.Document,
                            dbo.iLines.Part,
                            dbo.iLines.Pg,
                            dbo.iLines.Qty,
                            dbo.iLines.unit,
                            dbo.iHeads.[DateTime],
                            dbo.iLines.BinSeqNo,
                            dbo.Customer.cdisc,
                            dbo.Customer.bcs
                      ') i
left JOIN
dbo.NEWPareto
ON 
i.Part collate SQL_Latin1_General_CP1_CI_AS = dbo.NEWPareto.Part 
left JOIN
dbo.MyPgTable 
ON  
 i.pg collate SQL_Latin1_General_CP1_CI_AS = dbo.MyPgTable.[pGroup]

WHERE

 (i.[DateTime] BETWEEN @From AND @Too)

 AND (@Cdisc > 29 OR i.cdisc = @Cdisc)

 AND(@Acct = '0' 
 OR (@Acct = '1659%' AND i.Acct not Like @Acct) 
 OR (@Acct = '1557%' AND i.Acct Like @Acct)
 OR (@Acct = '18731%' AND i.Acct not Like '1873%' AND i.Acct not Like '1432%') 
 OR (@Acct != '1659%' AND i.Acct Like @Acct)) 

 AND(@bcs = '0' OR i.bcs != @bcs)

 AND i.pg != '60'
 AND i.pg != '61'
 AND i.pg != '62'

 GROUP BY i.Acct,
   i.Name, 
   i.Document, 
   i.Part, 
   i.Qty, 
   i.Unit, 
   dbo.NEWPareto.Pareto, 
   i.pg,
   dbo.MyPgTable.PgName, 
   i.[DateTime],
   i.BinSeqNo,
   i.cdisc,
   i.bcs

正如你所看到的,它相当长,但运行良好,有什么方法可以大幅提高速度吗?或者,使用链接服务器是问题所在吗?

感谢你们所有人帮助我回答这个问题,我很乐意选择你们所有人作为正确的答案,但我不能,所以请为所有人投票!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-03-29 17:20:08

左连接总是会使查询变得慢很多,跨多个数据库执行此操作会使查询变得更慢。

在OpenQuery中还有一个Group by,在末尾也有一个。也许用临时表(用i.parts和i.pg列上的索引)替换OpenQuery可以加快速度。

票数 3
EN

Stack Overflow用户

发布于 2012-03-29 17:15:40

AND i.pg != '60' AND i.pg != '61' AND i.pg != '62'

使用i.pg not in ('60','61','62')

如果您经常使用参数,请尝试使用sql计划指南

票数 2
EN

Stack Overflow用户

发布于 2012-03-29 17:40:22

最好避免使用链接服务器,它会对临时数据库造成严重破坏,不仅会导致正在运行的查询出现性能问题,还会影响数据库的整体性能。因为您使用的是SQL- server -2008,所以我建议不要在过程中执行跨服务器查询,而是将表变量传递给procudure。

要将表变量传递给存储过程,首先需要将表结构定义为新类型。例如:

代码语言:javascript
运行
复制
CREATE TYPE SACBAutoTable AS TABLE 
(    Acct    INT NOT NULL, 
     Name    VARCHAR(50) NOT NULL 
     ...etc
)

然后,您可以将其添加到存储过程定义中。例如:

代码语言:javascript
运行
复制
ALTER PROCEDURE [dbo].[GetSalesBuyers] 
      @SABCAutoTable  SACBAutoTable READONLY, 
      @Acct           VARCHAR(255),
      @Cdisc          VARCHAR(255),
      etc

在查询的后续部分,您可以更改

SELECT .... FROM OPENQUERY(

SELECT .... FROM @SABCAutoTable ...

最后,从c#调用该过程:

代码语言:javascript
运行
复制
SqlDataAdapter adapter = new SqlDataAdapter(YourCrossServerQuery, YourLinkedServerConnectionString);
DataTable table = new DataTable();
adapter.Fill(table);

using (SqlConnection connection = new SqlConnection(yourMainServerConnectionString))
{
    using (SqlCommand command = new SqlCommand(YourSP, connection))
    {
        connection.Open();
        command.Parameters.Add(new SqlParameter("@YourTableVariable", table));
        connection.Close();
    }
}

有关将表变量传递到存储过程的更多信息,请单击此处http://msdn.microsoft.com/en-us/library/bb510489.aspx

如果此操作的性能仍然很慢,则开始查看索引和其他常规查询整理工作,例如将AND != '60' AND != '61'更改为AND NOT IN ('60', '61')

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9922323

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档