使用SQL、SQL server manager 2008、c-sharp.net 4.0和ms visual studio professional 2010:
我一直在为我的程序编写一个主查询,到目前为止,它完全按照预期工作。唯一的问题是运行所需的时间。
有时,大约2000条记录最多需要3分钟。
我被要求更快地获得这个查询,但老实说,我不确定如何才能做到这一点。
查询如下,它使用一个链接服务器和4个表。3在一台服务器上,另一台在本地。
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正如你所看到的,它相当长,但运行良好,有什么方法可以大幅提高速度吗?或者,使用链接服务器是问题所在吗?
感谢你们所有人帮助我回答这个问题,我很乐意选择你们所有人作为正确的答案,但我不能,所以请为所有人投票!
发布于 2012-03-29 17:20:08
左连接总是会使查询变得慢很多,跨多个数据库执行此操作会使查询变得更慢。
在OpenQuery中还有一个Group by,在末尾也有一个。也许用临时表(用i.parts和i.pg列上的索引)替换OpenQuery可以加快速度。
发布于 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计划指南
发布于 2012-03-29 17:40:22
最好避免使用链接服务器,它会对临时数据库造成严重破坏,不仅会导致正在运行的查询出现性能问题,还会影响数据库的整体性能。因为您使用的是SQL- server -2008,所以我建议不要在过程中执行跨服务器查询,而是将表变量传递给procudure。
要将表变量传递给存储过程,首先需要将表结构定义为新类型。例如:
CREATE TYPE SACBAutoTable AS TABLE
( Acct INT NOT NULL,
Name VARCHAR(50) NOT NULL
...etc
)然后,您可以将其添加到存储过程定义中。例如:
ALTER PROCEDURE [dbo].[GetSalesBuyers]
@SABCAutoTable SACBAutoTable READONLY,
@Acct VARCHAR(255),
@Cdisc VARCHAR(255),
etc在查询的后续部分,您可以更改
SELECT .... FROM OPENQUERY(
至
SELECT .... FROM @SABCAutoTable ...
最后,从c#调用该过程:
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')
https://stackoverflow.com/questions/9922323
复制相似问题