我查询了如下产品库存:
<SetProperty Id="ARPINSTALLLOCATION" Value="[INSTALLDIR]" After="CreateFolders" Sequence="execute">NOT Installed</SetProperty>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="INSTALLDIR" Name="WinApp"/>
</Directory>
</Fragment>
此查询返回我想要的数据,并且它在我的桌面上运行正常,但是当我在较低规格的笔记本电脑上部署运行此查询的应用程序时,它非常慢并导致笔记本电脑挂起。我需要一些关于如何优化查询的帮助,或者可能需要更改它以使其更有效...提前感谢
答案 0 :(得分:1)
你能试试吗? (我没有测试就写了,因为你没有发布样本数据也没有创建表)。请检查并作为起点。比较查询和结果的结果,并比较执行计划。 对性能的分析需要“一些”Sql的知识和考虑几件事的能力(例如,有多少行,是否有索引,使用执行计划和统计等等)
SELECT C.PRODUCTID
,C.PRODUCTNAME
,COALESCE(D.QTY_SOLD,0) AS QTY_SOLD
,COALESCE(E.QTY_STOCKS,0) AS QTY_STOCKS
,COALESCE(E.QTY_STOCKS,0)-COALESCE(D.QTY_SOLD,0) AS REMAININGSTOCK
FROM PRODUCTS C
LEFT JOIN (SELECT PRODUCTID, SUM(QTY) AS QTY_SOLD
FROM INVOICEDETAILS
GROUP BY PRODUCTID
) D ON B.PRODUCTID = D.PRODUCTID
LEFT JOIN (SELECT PRODUCTID,SUM(QTYRECEIVE) AS QTY_STOCKS
FROM PURCHASEORDERDETAILS
GROUP BY PRODUCTID
) E ON B.PRODUCTID = E.PRODUCTID
答案 1 :(得分:1)
所以我在选择中删除了你的子查询,我不认为这些是必要的。我也在你的连接中移动并给表提供了更好的别名;
SELECT
b.ProductID,
c.ProductName,
ISNULL(SUM(id.Qty),0) as Sold,
ISNULL(SUM(pod.QtyReceive),0) as Stocks,
ISNULL(SUM(pod.QtyReceive),0) - ISNULL(SUM(id.Qty),0) as RemainingStock
FROM PurchaseOrderDetails pod
INNER JOIN Products pr
ON pr.ProductID = pod.ProductID
LEFT JOIN InvoiceDetails id
ON id.ProductID = pod.ProductID
GROUP BY
pod.ProductID, pr.ProductName
您已经加入了这两个表,因此您根本不需要选择子查询。我还在ISNULL中包装了SUM,以确保没有NULL错误。
我建议在代码开头使用SET STATISTICS TIME,IO ON
(最后使用OFF命令)。然后复制“&#39;消息”中的所有文字。选项卡进入statisticsparser.com。为查询和比较执行此操作,检查总CPU时间和逻辑读取,您希望这些都更低,以获得更好的性能。我打赌你的逻辑读取会因这个新查询而显着下降。
修改强>
好的,我已根据您的示例数据整理了一个新查询。我只使用了此查询实际需要的字段,因此对于此示例来说更简单。
样本数据
CREATE TABLE #InvoiceDetails (ProductID int, Qty int)
INSERT INTO #InvoiceDetails (ProductID,Qty)
VALUES (3,50),(1,0),(2,1),(1,12),(2,1),(3,1),(1,1),(2,1),(1,1),(2,1)
CREATE TABLE #PurchaseOrderDetails (ProductID int, Qty int)
INSERT INTO #PurchaseOrderDetails (ProductID, Qty)
VALUES (1,100),(2,20),(4,10),(1,12),(5,12),(4,12),(3,12),(2,20),(3,20),(4,20),(5,20)
CREATE TABLE #Products (ProductID int, ProductName varchar(20))
INSERT INTO #Products (ProductID, ProductName)
VALUES (1,'Sample Product'),(2,'DYE INK CYAN'),(3,'test Product 1'),(4,'test Product 2'),(5,'test Product 3'),(1004,'TESTING PRODUCT')
为此,这是原始查询的输出
ProductID ProductName Sold Stocks RemainingStock
1 Sample Product 14 112 98
2 DYE INK CYAN 4 40 36
3 test Product 1 51 32 -19
4 test Product 2 0 42 42
5 test Product 3 0 32 32
这是我使用的重写查询。注意,SELECT语句中没有子查询,它们应该在连接中。另请注意,由于我们在子查询中进行聚合,因此我们也不需要在外部查询中执行此操作。
SELECT
pod.ProductID,
pr.ProductName,
ISNULL(id.Qty,0) as Sold,
ISNULL(pod.Qty,0) as Stocks,
ISNULL(pod.Qty,0) - ISNULL(id.Qty,0) as RemainingStock
FROM #Products pr
INNER JOIN (SELECT ProductID, SUM(Qty) Qty FROM #PurchaseOrderDetails GROUP BY ProductID) pod
ON pr.ProductID = pod.ProductID
LEFT JOIN (SELECT ProductID, SUM(Qty) Qty FROM #InvoiceDetails GROUP BY ProductID) id
ON id.ProductID = pr.ProductID
这是新输出
ProductID ProductName Sold Stocks RemainingStock
1 Sample Product 14 112 98
2 DYE INK CYAN 4 40 36
3 test Product 1 51 32 -19
4 test Product 2 0 42 42
5 test Product 3 0 32 32
哪个与原始查询相符。
我建议在您的计算机上尝试此查询并查看哪个表现更好,请尝试我之前提到的STATISTICS TIME,IO命令。
答案 2 :(得分:1)
按b.ProductID, c.ProductName
分组,您可以使用aggregate
函数进行计算。
并在表格中创建indexes
以提高效果。
Select
b.ProductID, c.ProductName,
SUM(isnull(a.Qty,0)) as Sold,
SUM(b.QtyReceive) as Stocks,
SUM(b.QtyReceive) - SUM(isnull(a.Qty,0)) as RemainingStock
from
PurchaseOrderDetails b
LEFT JOIN InvoiceDetails a on a.ProductID = b.ProductID
INNER JOIN Products c on b.ProductID = c.ProductID
Group By
b.ProductID, c.ProductName
答案 3 :(得分:0)
查看您的查询,我认为这可能是等效的(或至少我希望是这样):
Select
b.ProductID
, c.ProductName
, Case When SUM(a.Qty) IS NULL then 0 else SUM(a.Qty) end as sold
, Case When SUM(b.QtyReceive) IS NULL then 0 else SUM(b.QtyReceive) end as Stock
, Case When SUM(isnull(a.Qty,0 ) - isnull(b.QtyReceive,0)) IS NULL
then 0
else SUM(isnull(a.Qty,0 ) - isnull(b.QtyReceive,0)) end as RemainingStock
from Products c
left join InvoiceDetails a on c.ProductID = a.ProductID
left join PurchaseOrderDetails b on c.ProductID = b.ProductID
Group By b.ProductID,c.ProductName