SQL 视图中未使用字段的性能
我正在使用 MS SQL Server。
当我定义数据库模式时,我定义了一个(非物化)视图,其中包括许多字段,例如如下(其中“Topic”是表的名称,视图是Topic表上的自联接) :
CREATE VIEW View_Topic_Ancestor AS
SELECT
Subordinate.Id AS Subordinate_Id,
Subordinate.Folder_Id AS Subordinate_Folder_Id,
Subordinate.topicTitle AS Subordinate_topicTitle,
Subordinate.topicXhtml AS Subordinate_topicXhtml,
Subordinate.crossLinked AS Subordinate_crossLinked,
Superior.Id AS Superior_Id,
Superior.topicTitle AS Superior_topicTitle,
Superior.topicXhtml AS Superior_topicXhtml,
Superior.crossLinked AS Superior_crossLinked
FROM Topic AS Subordinate LEFT OUTER JOIN Topic AS Superior
ON Superior.Folder_Id = Subordinate.Folder_Id
AND
Superior.LeftValue = (SELECT MAX(Ancestor.LeftValue)
FROM Topic AS Ancestor
WHERE Subordinate.LeftValue > Ancestor.LeftValue
AND Subordinate.LeftValue < Ancestor.RightValue
AND Subordinate.Folder_Id = Ancestor.Folder_Id)
稍后(在运行时)我在 select 语句中使用此视图,如下所示:
SELECT
T.Id AS Shared_Id,
V.Superior_Id,
V.Superior_topicTitle,
V.Subordinate_Id,
V.Subordinate_Folder_Id,
V.Subordinate_topicXhtml
FROM Topic AS T, View_Topic_Ancestor AS V
WHERE Folder_Id='e2eb2b68-738d-49ad-9787-a1e655b7973f'
AND T.crossLinked = V.Subordinate_Id
此 SELECT 语句不引用(不选择)视图中的许多字段:例如,它选择 Subordination_topicXhtml字段,但它不选择 Superior_topicXhtml 字段。
我的问题是:
1)在视图中定义但在视图的运行时选择中未引用的字段对性能有很大影响吗? 假设您愿意,Superior_topicXhtml 字段包含大量数据(是一个很长的字符串)。
2)我如何自己验证这个答案? 测试(用秒表测量经过的时间)是唯一的方法,还是有可能根据理论获得答案? 我正在使用适用于 Microsoft SQL Server 2008 的“Microsoft Server SQL Management Studio”和 SQL Express。 我了解如何获取(但尚未学会如何解释)此查询的“估计执行计划”,但这仅显示正在发生的索引和循环,而不显示是否从未引用的字段检索数据。
I'm using MS SQL Server.
When I define the database schema I define a (non-materialized) view, which includes many fields, for example as follows (where "Topic" is the name of a table, and the view is a self-join on the Topic table):
CREATE VIEW View_Topic_Ancestor AS
SELECT
Subordinate.Id AS Subordinate_Id,
Subordinate.Folder_Id AS Subordinate_Folder_Id,
Subordinate.topicTitle AS Subordinate_topicTitle,
Subordinate.topicXhtml AS Subordinate_topicXhtml,
Subordinate.crossLinked AS Subordinate_crossLinked,
Superior.Id AS Superior_Id,
Superior.topicTitle AS Superior_topicTitle,
Superior.topicXhtml AS Superior_topicXhtml,
Superior.crossLinked AS Superior_crossLinked
FROM Topic AS Subordinate LEFT OUTER JOIN Topic AS Superior
ON Superior.Folder_Id = Subordinate.Folder_Id
AND
Superior.LeftValue = (SELECT MAX(Ancestor.LeftValue)
FROM Topic AS Ancestor
WHERE Subordinate.LeftValue > Ancestor.LeftValue
AND Subordinate.LeftValue < Ancestor.RightValue
AND Subordinate.Folder_Id = Ancestor.Folder_Id)
Later (at run-time) I use this view in a select statement, like this:
SELECT
T.Id AS Shared_Id,
V.Superior_Id,
V.Superior_topicTitle,
V.Subordinate_Id,
V.Subordinate_Folder_Id,
V.Subordinate_topicXhtml
FROM Topic AS T, View_Topic_Ancestor AS V
WHERE Folder_Id='e2eb2b68-738d-49ad-9787-a1e655b7973f'
AND T.crossLinked = V.Subordinate_Id
This SELECT statement doesn't reference (doesn't select) many of the fields which are in the view: for example, it selects the Subordinate_topicXhtml field but it doesn't select the Superior_topicXhtml field.
My questions are:
1) Do the fields which are defined in the view, but which are not referenced in the run-time selection from the view, have much effect on performance? Assume if you will that the Superior_topicXhtml field contains a lot of data (is a very long string).
2) How can I verify the answer to this myself? Is testing (measuring ellapsed time with a stop-watch) the only way, or is it possible to obtain an answer based on theory? I am using "Microsoft Server SQL Management Studio" for Microsoft SQL Server 2008, with SQL Express. I see how to obtain (but haven't learned how to interpret) the "estimated execution plan" for this query, but this shows only what indexes and loops are happening, not whether data is being retrieved from unreferenced fields.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
查询优化器通过将定义视图的 sql 与您构造的从视图中“选择”的 sql 组合到单个 sql 查询中来创建查询计划。 如果在这个组合的、优化的sql中,任何特定的属性(列)不是必需的,则不会使用它。具体来说,如果最终的选择不需要它,则不会通过网络发送它。 另外,如果任何Where子句、Order By或优化sql中的任何其他子句都不需要它,并且所需的所有属性恰好都在索引中,那么该查询只能读取索引,而不会触及索引表根本...即使他视图引用了索引中不存在的列...您可以通过查看查询的查询执行计划来看到这一点。
The Query optimizer creates a query plan by combining the sql which defines the view with the sql you construct to "select" from the view into a single sql query. If, in this combined, optimized sql, any specific attribute (column) is not necessary, it will not be used.. specifically, if the final select does not require it, it will not be sent over the wire. Also, if it is not needed by any Where clause, or Order By or anything else within the optimized sql, and all the attributes that ARE needed happen to be in an index, then that query can read only the index, and not touch the table at all... even thought he view references a column not present in the index... You can see this by looking at the query execution plan for the query.
当 Management Studio 中显示查询的执行计划时,您可以使用鼠标将鼠标悬停在执行计划中的节点上。
当您将鼠标悬停时,会显示一个大的工具提示:其中包括该节点检索的字段的“输出列表”,以及显示读取这些字段的实例数的“估计行数”字段。
When you have the query's Execution plan displayed in the Management Studio, you can use the mouse to hover over nodes in the execution plan.
When you hover, a large tool-tip is displayed: which includes an "Output List" of the fields retrieved by that node, and an "Estimated Number of Rows" fields which shows how many instances of those fields are read.