这取决于,但在很大程度上很少见。
假设我们有这样的视图:
CREATE VIEW TestView
AS
Select A.x, B.y, B.z
FROM A JOIN B on A.id = B.id
我们为此创建了一个实体映射。
我们还假设 B.id 已绑定,因此它不可为空,并且与 A.id 具有外键关系 - 也就是说,只要有 B 行,总是至少有一个对应的 @987654325 @。
现在,如果我们可以用from t in context.TestView where t.x == 3 代替from a in context.A join b in context.B on a.id equals b.id where a.x == 3 select new {a.x, b.y, b.z}。
我们可以预期前者转换为 SQL 的速度会稍微快一些,因为它是一个稍微简单的查询(从 Linq 和 SQL 的角度来看)。
我们可以预期后者从 SQL 查询转换为 SQLServer(或其他)内部查询的速度会稍微快一些。
我们可以预期内部查询几乎相同,除非有些奇怪。因此,我们预计此时的性能是相同的。
总而言之,它们之间没有太多选择。如果我必须赌一个,我会用视图稍微快一点的情况下赌注,尤其是在第一次跟注时,但我不会下很多赌注。
现在让我们考虑(from t in context.TestView select t.z).Distinct()。与(from b in context.B select b.z).Distinct().
这两个都应该变成一个非常简单的SELECT DISTINCT z FROM ...。
这两者都应该变成只对表B进行表扫描或索引扫描。
第一个可能不是(查询计划中的缺陷),但这会令人惊讶。 (对类似视图的快速检查确实发现 SQLServer 忽略了不相关的表)。
第一个可能需要稍长的时间来生成查询计划,因为必须推断出 A.id 上的连接是无关紧要的事实。但是数据库服务器擅长这种事情;这是一组计算机科学和问题,已经完成了数十年的工作。
如果我必须押注其中一个,我会押注让事情变得稍微慢一些的观点,尽管我更押注它是如此微小的差异以至于它消失了。对这两种查询的实际测试发现两者在相同的差异范围内(即两者的不同时间范围相互重叠)。
在这种情况下,从 linq 查询生成 SQL 的效果将为零(此时它们实际上是相同的,但名称不同)。
让我们考虑一下我们是否在该视图上有一个触发器,以便插入或删除执行等效的插入或删除。在这里,我们将从使用一个 SQL 查询而不是两个(或更多)查询中获得一些好处,并且更容易确保它发生在单个事务中。因此,在这种情况下,浏览量略有增加。
现在,让我们考虑一个更复杂的视图:
CREATE VIEW Complicated
AS
Select A.x, B.x as y, C.z, COALESCE(D.f, D.g, E.h) as foo
FROM
A JOIN B on A.r = B.f + 2
JOIN C on COALESCE(A.g, B.x) = C.x
JOIN D on D.flag | C.flagMask <> 0
WHERE EXISTS (SELECT null from G where G.x + G.y = A.bar AND G.deleted = 0)
AND A.deleted = 0 AND B.deleted = 0
我们可以在 linq 级别完成所有这些工作。如果我们这样做了,随着查询生产的进行,它可能会有点昂贵,尽管这很少是 linq 查询整体命中中最昂贵的部分,尽管编译查询可能会平衡这一点。
我倾向于将视图作为更有效的方法,但如果这是我使用该视图的唯一原因,我会介绍一下。
现在让我们考虑:
CREATE VIEW AllAncestry
AS
WITH recurseAncetry (ancestorID, descendantID)
AS
(
SELECT parentID, childID
FROM Parentage
WHERE parentID IS NOT NULL
UNION ALL
SELECT ancestorID, childID
FROM recurseAncetry
INNER JOIN Parentage ON parentID = descendantID
)
SELECT DISTINCT (cast(ancestorID as bigint) * 0x100000000 + descendantID) as id, ancestorID, descendantID
FROM recurseAncetry
从概念上讲,此视图执行大量选择;进行选择,然后根据该选择的结果递归地进行选择,依此类推,直到它具有所有可能的结果。
在实际执行中,这会转化为两次表扫描和一次惰性假脱机。
基于 linq 的等价物会更重;真的,你最好要么调用等效的原始 SQL,要么将表加载到内存中,然后在 C# 中生成完整的图表(但请注意,这将浪费基于不需要的查询一切)。
总而言之,在这里使用视图会节省很多。
总结;使用视图通常对性能的影响可以忽略不计,而且这种影响可以是任何一种方式。使用带有触发器的视图可以稍微提高性能,并通过强制数据在单个事务中发生更容易确保数据完整性。使用带有 CTE 的视图可以大大提高性能。
使用或避免使用视图的非性能原因是:
视图的使用在代码中隐藏了与该视图相关的实体和与基础表相关的实体之间的关系。这很糟糕,因为您的模型现在在这方面不完整。
1234563 /p>