【发布时间】:2012-08-21 01:22:51
【问题描述】:
我有一个似乎无法完全调整的视图,因此我尝试将其转换为 proc,将查询时使用的 WHERE 条件之一移动到参数中并在派生表中使用该参数。
查看
CREATE VIEW myView
AS
SELECT i.ItemCode
, s.StoreID
, ISNULL(SUM(s.TotalSales)) AS Sales
FROM Item i
LEFT JOIN Balance b ON i.ItemCode = b.ItemCode
LEFT JOIN (SELECT SUM(Quantity)
, StoreID
, ItemCode
, Date
FROM Sales
GROUP BY StoreID
, ItemCode
, Date) AS s ON i.ItemCode = s.ItemCode
AND s.Data >= COALESCE(b.Date, '01-01-1900)
JOIN
GROUP BY i.ItemCode
, s.StoreID
存储过程
CREATE PROCEDURE myProc(@StoreID INT)
AS
SELECT i.ItemCode
, s.StoreID
, ISNULL(SUM(s.TotalSales)) AS Sales
FROM Item i
LEFT JOIN Balance b ON i.ItemCode = b.ItemCode
LEFT JOIN (SELECT SUM(Quantity)
, StoreID
, ItemCode
, Date
FROM Sales
WHERE StoreID = @StoreID
GROUP BY StoreID
, ItemCode
, Date) AS s ON i.ItemCode = s.ItemCode
AND s.Data >= COALESCE(b.Date, '01-01-1900)
JOIN
GROUP BY i.ItemCode
, s.StoreID
EXEC myProc(100) 比 SELECT * FROM myView WHERE StoreID = 100 快很多。 应该是这样吗?
注意:我知道这段代码可能没有完美的意义或无法运行——我试图通过删除其他一些 JOIN 来简化它。实际代码中唯一的实质性区别是将 WHERE 移到派生表中,我在这里已经完成了。
视图不应该在执行派生表查询时考虑我的 WHERE 并与 proc 一样快吗?
感谢您的帮助!
【问题讨论】:
-
我正在尝试将实体框架与此查询一起使用,使用视图会更好。
-
是的,视图可能应该更慢。首先生成视图:来自 Item、Balance 和 Sales 子查询的所有项目将被连接在一起。可能有不少记录。然后,从该集合中应用过滤器。在 proc 中,过滤器首先应用于 Sales 表,然后将这个小子集连接到其他表。因此,如果 StoreIds 的基数与 Sales 中的记录数相比较小,那么您看到的结果将是预期的。
-
在查询视图时,有什么方法可以根据我在 WHERE 子句中提供的条件过滤派生查询?
-
参数化视图。这个SO Question 似乎回答了这个问题,有点像你正在做的事情。由于我对sql server不熟悉,所以不能多说。
标签: sql sql-server performance stored-procedures sqlperformance