我有这个查询,但是它非常慢,并且将每个人都锁定在数据库之外,直到它解决了,我仍然可以加快它的速度。
SELECT Item.Barcode,
Hetype.Description,
Max(StockTakeDetails.xStockTake),
Max(OpScans.ScanDate) AS Max_ScanDate
FROM Item
INNER JOIN Hetype ON Item.Type = Hetype.Type
LEFT JOIN StockTakeDetails ON StockTakeDetails.xItemID = Item.Itemref
LEFT JOIN OpScans ON Item.Itemref = OpScans.xItemRef
WHERE Item.Lastservice = 1 AND
Item.Deleted = FALSE AND
Item.CommissionStatus <> 4
GROUP BY Item.Barcode,
Hetype.Description
答案 0 :(得分:2)
我假设您正在使用SQL Server。如果没有,则此答案将不适用。
问题是您当前遇到读者阻止作者的情况。为了防止这种情况,您的数据库应配置为启用 multiversioning 。
这可以通过在SQL Server中打开“读取提交的快照隔离”来实现。
以下是有关此过程的不错的文章:Implementing Snapshot or Read Committed Snapshot Isolation in SQL Server: A Guide
Oracle数据库已经有数十年的多版本化(读者不会阻止作者,而作家也不会阻止读者),因此,Oracle开发人员通常会假设它在所有数据库中都相同,但是事实并非如此。 。 不过,SQL Server确实支持此功能,但默认情况下未启用该功能。
最后,您可以在紧急情况下使用一个非常粗糙的SQL Server技巧:将NOLOCK
提示添加到查询中。从长远来看,这不是一个好主意,并且可能导致读取错误。不过,如果您的查询是针对未用于报告的摘要网页,则可能是这种廉价而愉悦的黑客手段的合理选择。
读取提交的快照隔离是更好的解决方案。
答案 1 :(得分:2)
您提供的信息很少,无法帮助您进行优化。您的问题没有数据库标签。它没有有关表或执行计划的大小信息。
但是,您似乎正在将一个表连接到两个不同的表,从而产生笛卡尔乘积。这可能是性能的根源。问题,所以我建议使用相关子查询重写查询:
SELECT i.Barcode, ht.Description,
(SELECT MAX(std.xStockTake),
FROM StockTakeDetails std
WHERE std.xItemID = i.Itemref
),
(SELECT MAX(os.ScanDate)
FROM OpScans os
WHERE os.xItemRef = i.Itemref
) AS Max_ScanDate
FROM Item i JOIN
Hetype ht
ON i.Type = ht.Type
WHERE i.Lastservice = 1 AND
i.Deleted = FALSE AND
i.CommissionStatus <> 4
GROUP BY i.Barcode, ht.Description ;
然后对于此查询,您需要以下索引:
Item(LastService, Deleted, CommissionStatus, Itemref)
HeType(Type, Description)
StockTakeDetails(xItemID, xStockTake)
OpScans(xItemID, ScanDate)
也许还有其他改进,但是我怀疑这将解决您的性能问题。