【发布时间】:2010-09-21 07:43:19
【问题描述】:
首先,一些背景。
我们有一个订单处理系统,工作人员在该系统中将有关订单的计费数据输入应用程序中,该应用程序将其存储在 sql server 2000 数据库中。这个数据库不是真正的计费系统:它只是一个保存位置,以便记录可以通过夜间批处理运行到大型机系统中。
此批处理是由外部供应商提供的罐装第三方包。它应该做的部分工作是为任何被拒绝的记录提供报告。拒绝报告是手动处理的。
不幸的是,第三方软件并没有捕捉到所有的错误。我们有单独的进程将数据从大型机拉回数据库中的另一个表中,并将拒绝的费用加载到另一个表中。
然后会运行审核流程,以确保员工最初输入的所有内容都可以在某个地方进行说明。该审计采用我们运行的 sql 查询的形式,它看起来像这样:
SELECT *
FROM [StaffEntry] s with (nolock)
LEFT JOIN [MainFrame] m with (nolock)
ON m.ItemNumber = s.ItemNumber
AND m.Customer=s.Customer
AND m.CustomerPO = s.CustomerPO -- purchase order
AND m.CustPORev = s.CustPORev -- PO revision number
LEFT JOIN [Rejected] r with (nolock) ON r.OrderID = s.OrderID
WHERE s.EntryDate BETWEEN @StartDate AND @EndDate
AND r.OrderID IS NULL AND m.MainFrameOrderID IS NULL
当然,这是经过大量修改的,但我相信重要的部分都得到了体现。问题是这个查询开始需要很长时间才能运行,我正在尝试找出如何加快它的速度。
我很确定问题是从 StaffEntry 表到 MainFrame 表的 JOIN。由于两者都保存了自一开始(本系统中为 2003 年)以来的每个订单的数据,因此它们往往有点大。 StaffEntry 表中使用的OrderID 和EntryDate 值在导入到大型机时不会保留,这就是连接稍微复杂一些的原因。最后,由于我要在 MainFrame 表中查找不存在的记录,因此在执行 JOIN 后,我们在 where 子句中有那个丑陋的 IS NULL。
StaffEntry 表由 EntryDate(集群)索引,并在 Customer/PO/rev 上单独索引。 MainFrame 由客户和主机费用编号(集群,其他系统需要)和客户/PO/Rev 单独索引。 Rejected 根本没有被索引,但它很小,测试表明这不是问题。
所以,我想知道是否有另一种(希望更快)方式可以表达这种关系?
【问题讨论】:
-
你的表有什么索引?
-
能否提供查询的执行计划?
-
现在包含索引,但执行计划无法正常工作,因为它与我发布的查询的模糊版本不匹配。
标签: sql sql-server performance join sql-server-2000