【发布时间】:2015-09-03 21:50:20
【问题描述】:
我在 stackoverflow 上的第一篇文章(随着时间的推移对我有很大帮助):
我有一个带有交叉连接的查询,当我使用 where 子句运行它时它工作正常,但当我将它放在视图中并应用 where 视图的子句。
我认为问题在于,当代码封装在视图中时,SQL 没有将 where 子句应用于交叉连接,因此最终有数百万行(而不是这里的 180案例)。
代码如下 - 它是一个查询,它使用平均预期每月使用量和传入订单列表来预测仓库中物品的未来现有库存。
CREATE VIEW [dbo].[ItemWarehouseStockForecastDaily2]
AS
SELECT
fd.AsafterDate
, iw.idItem
, iw.idWarehouse
, iw.OnHandQuantity
+ SUM(ISNULL(iwio.PurchaseOrderInboundQuantity, 0)
- iws.AverageMonthlyDemandQuantity / (365.25/12)
) OVER (ORDER BY fd.AsafterDate) AS OnHandQuantity
FROM
(
( SELECT CalendarDate Asafterdate
FROM Calendar c
WHERE c.CalendarDate > GETDATE()
AND c.CalendarDate < DATEADD(d, 180, GETDATE())
) fd -- This table has 180 rows
-- This table has 10 million rows - one per item per warehouse
CROSS JOIN ItemWarehouse iw
)
LEFT JOIN ItemWarehouseDemandFromStockStatisticsMonthly iws
ON iws.idItem = iw.idItem
AND iws.idWarehouse = iw.idWarehouse
LEFT JOIN ItemWarehouseInboundAndOutboundQuantitiesWithDueDate iwio
ON iwio.idItem = iw.idItem
AND iwio.idWarehouse = iw.idWarehouse
AND iwio.DueDate = fd.Asafterdate
/*
WHERE iw.idItem = 12345
AND iw.idWarehouse = 67
ORDER BY AsafterDate
*/
注释掉的 where 子句使查询在不在视图中时(按 idwarehouse、iditem 聚类的表)快速运行(亚秒级)
我们将不胜感激任何/所有帮助和建议。
【问题讨论】:
-
将
itemWarehouse作为查询中的基表是否有意义? -
如果我不得不猜测,这是一个执行计划问题。您是否尝试将 OPTION (RECOMPILE) 添加到您的选择语句中?
-
我并不是说这是一个答案,但如果你使用表格函数而不是视图,如果你能告诉我结果,我是居里夫人!即将所有视图代码放入一个表函数并运行相同的测试。速度和视图一样吗?我发现表函数在这类事情上会好很多。
-
嗨 Stephan,你是对的 - 这绝对是一个执行计划问题 - 服务器没有将 where 子句与交叉连接相关联,因此该部分返回 4.6 亿行而不是 180 行然后服务器必须使用 where 子句过滤回 180。我就是找不到告诉服务器的方法!
-
嗨@Paul,感谢您的建议。只要我将 idItem 和 idWarehouse 作为参数传递,表函数值就可以很好地工作。当我只使用 where 子句时,我又迷路了。不幸的是,在使用 union 结合历史库存水平数据后,我暂时通过 MS Access 表单发布结果,因此查看会非常方便..
标签: sql-server tsql sql-server-2014