我有以下的看法:
SELECT
poHeader.No_ AS PONumber,
poHeader.[Buy-from Vendor No_] AS VendorNumber,
poHeader.[Document Date] AS DocumentDate,
vendor.Name AS VendorName,
vendor.Contact AS VendorContact,
vendor.[E-Mail] AS VendorEmail,
vendor.Address AS VendorAddress,
vendor.[Address 2] AS VendorAddress2,
vendor.City AS VendorCity,
vendor.County AS VendorCounty,
vendor.[Post Code] AS VendorPostCode,
vendor.[Phone No_] AS VendorPhone,
vendor.[Fax No_] AS VendorFax,
salesHeader.No_ AS SONumber,
poHeader.[Order Date] AS OrderDate,
salesHeader.[Crocus Comment] AS CrocusComment,
salesHeader.GiftMessage,
salesHeader.[Delivery Comment] AS DeliveryComment,
salesHeader.[Shipment Date] AS DeliveryDate,
COALESCE (salesHeader.[Ship-to Name],
poHeader.[Ship-to Name]) AS DeliveryName,
COALESCE (salesHeader.[Ship-to Address],
poHeader.[Ship-to Address]) AS DeliveryAddress,
COALESCE (salesHeader.[Ship-to Address 2],
poHeader.[Ship-to Address 2]) AS DeliveryAddress2,
COALESCE (salesHeader.[Ship-to City],
poHeader.[Ship-to City]) AS DeliveryCity, COALESCE (salesHeader.[Ship-to County],
poHeader.[Ship-to County]) AS DeliveryCounty,
COALESCE (salesHeader.[Ship-to Post Code],
poHeader.[Ship-to Post Code]) AS DeliveryPostcode,
salesHeader.DeliveryPhoneNo, poForEmailing.Processed,
poForEmailing.Copied
FROM
Navision4.dbo.[Crocus Live$Purch_ orders for e-mailing] AS poForEmailing
LEFT OUTER JOIN
Navision4.dbo.[Crocus Live$Purchase Header] AS poHeader ON poForEmailing.No_ = poHeader.No_
INNER JOIN
Navision4.dbo.[Crocus Live$Vendor] AS vendor ON poHeader.[Buy-from Vendor No_] = vendor.No_
LEFT OUTER JOIN
Navision4.dbo.[Crocus Live$Sales Header] AS salesHeader ON salesHeader.No_ = dbo.fnGetSalesOrderNumber(poHeader.No_)
这个视图是在一个名为NavisionMeta的数据库中创建的,它查询一个(在同一服务器上)与Navision4相关的数据库
我最近将两个数据库都转移到了新的(更好的)硬件上。不确定这是否相关,但新硬件使用SQL 2008,而旧硬件运行SQL 2000
如果我在SQL Management Studio中使用以下查询进行查询,则需要2分钟以上的时间:
SELECT *
FROM [NavisionMeta].[dbo].[PurchaseOrders]
WHERE Processed=0 AND Copied=0
这太长了!
LINQ中的以下查询全部超时,即使我将超时调整为5分钟!
var purchaseOrdersNotProcessed = (from p in db.PurchaseOrders
where p.Copied.Equals(0)
&& p.Processed.Equals(0)
select p).ToList();
令我困惑的是,在以前的硬件上,它工作得很好!
以防万一,上面使用的udf是:
CREATE FUNCTION [dbo].[fnGetSalesOrderNumber](@PONumber varchar(20))
RETURNS varchar(20)
AS
BEGIN
RETURN (
SELECT
TOP 1 [Sales Order No_]
FROM
Navision4.dbo.[Crocus Live$Purchase Line]
WHERE
[Document No_] = @PONumber
)
发布于 2010-01-08 19:56:27
您还可以考虑更新统计信息。
发布于 2010-03-09 02:36:30
左内连接?嗯,我不确定这是否会有帮助...
如果这个查询之前是有效的(数据而不是性能),那么上面的查询将从将所有连接转换为内部连接中受益。因为您是使用来自poHeader (即外部连接)的值的内部JOINing供应商,所以您实际上也对poHeader提出了内部连接要求(除了外部连接可能会影响性能)。Vendor不能返回值,除非poHeader具有值,并且由于vendor是内部联接的,因此如果poHeader中没有值,则整行将被忽略。salesHeader也是如此。连接中使用的函数需要poHeader中的值(根据上面的逻辑,该值必须有一个值),因此这个连接也将受益于成为显式的内部连接,而不仅仅是隐式连接。
除此之外,我确实同意关于索引的陈述(除了关于很少需要外部联接的陈述。这就像是说,如果你有锤子,就不需要螺丝刀)。索引听起来像是对较弱性能的最合理解释。具体地说,您应该检查您的poForEmailing别名表是否具有索引(已处理,已复制)。如果没有该索引,当数据大小增加一倍时,您的查询时间至少会增加一倍,因为该表中的每条记录都需要根据这些谓词进行测试。关于你最初的问题,在其他条件相同的情况下,我没有注意到SQL Server2008中有任何东西会在性能上有这样的变化。
发布于 2010-01-08 13:32:09
起始点可能是在旧机器和新机器上查看查询的执行计划。与较新版本的SQL Server相比,肯定会有优化方面的差异。执行计划可能会告诉您,索引是必需的,但由于某些原因,该索引在以前的版本中并不那么关键。
https://stackoverflow.com/questions/2027764
复制相似问题