使用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
正如你可以看到它很长但工作正常,有没有办法大幅度提高速度?或正在使用链接服务器的问题?
感谢大家帮助我解决这个问题,我很乐意为你选择正确的答案,但我不能,所以取而代之的是所有人的选票!
答案 0 :(得分:3)
左连接总是使查询慢得多,在多个数据库中执行此操作会使其更慢。
OpenQuery中还有一个Group by,最后还有一个。也许用一个临时表替换OpenQuery(在i.parts和i.pg列上有一个索引)会加快速度。
答案 1 :(得分:2)
AND i.pg != '60'
AND i.pg != '61'
AND i.pg != '62'
使用i.pg not in ('60','61','62')
如果您经常使用参数,请尝试使用sql计划指南
答案 2 :(得分:1)
最好避免使用链接服务器,它会对Temp DB造成严重破坏,不仅会导致正在运行的查询出现性能问题,而且还会影响整个数据库的性能。由于您使用的是SQL-Server-2008,我建议不要在过程中执行跨服务器查询,而是将表变量传递给procudure。
要将表变量传递给存储过程,首先需要将表结构定义为新类型。 e.g:
CREATE TYPE SACBAutoTable AS TABLE
( Acct INT NOT NULL,
Name VARCHAR(50) NOT NULL
...etc
)
然后,您可以将其添加到存储过程定义中。 e.g。
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')