【问题标题】:Multiple column Indexes of tables in view joins视图连接中表的多列索引
【发布时间】:2014-04-24 14:02:07
【问题描述】:

您好,我有一个使用 ID 加入的视图,该 ID 在联接中使用客户编号。但是没有单独的 CustomerNo 索引,而是带有 ID。这些连接是否使用索引?

(让我表明我相信我没有解释它) 视图是这样的

Select T1.CustomerNo, T1.X, T1.Y, T2.Z 
from T1 inner join T2 on T1.Id = T2.Id

此视图将用于一些动态查询,并且主要在连接上使用 CustomerNo。在 T1 表上,ID 上有一个聚集索引,(ID,CustomerNo) 上有一个非聚集索引

查询是否通过 CustomerNo 加入视图使用此索引,或者我应该在 CustomerNo 上添加单独的索引。

【问题讨论】:

  • 看看执行计划,里面有所有需要的答案。
  • 我没有问题。它们是动态生成的。我要求的是一般原则

标签: sql-server indexing views


【解决方案1】:

嗯,这取决于。优化器对索引的选择受许多因素的影响,包括基数和谓词的选择性。可能是对于相同的查询,但参数不同,优化器一次生成使用索引的执行计划,而另一次不生成。你真的应该检查实际的计划。

要从缓存中获取计划,请使用以下查询:

select text, cast(query_plan as xml)
from sys.dm_exec_cached_plans
cross apply sys.dm_exec_sql_text(plan_handle)
cross apply sys.dm_exec_text_query_plan(plan_handle, 0, -1)
-- add a filter on the text column to isolate the interesting queries only

此外,如果您对哪些查询使用了特定索引感兴趣,也可以从计划缓存中找到(当然,仅针对缓存计划)

declare @IndexName sysname
set @IndexName = 'name_of_the_index';

with xmlnamespaces ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' as p)
select 
     db_name(dbid) + '.' + object_schema_name(objectid, dbid) + '.' + object_name(objectid, dbid) AS database_object
     ,iobj.value('@Index','sysname') AS IndexName
     ,qp.query_plan
     ,iobj.query('.') AS IndexUsage
 from sys.dm_exec_cached_plans cp 
 cross apply sys.dm_exec_query_plan(cp.plan_handle) qp
 cross apply query_plan.nodes('//p:RelOp') IndexScan(scan)
 cross apply scan.nodes('//p:Object') as IndexObject(iobj)
 where dbid = db_id()
 and iobj.value('@Index','nvarchar(max)') = QUOTENAME(@IndexName,'[')

第二个查询可能需要一些时间并使用一些资源,请小心。

【讨论】:

  • 谢谢,但我无权在生产环境中运行这些。根据用户在基于规则的屏幕上的选择,查询在早上以批处理方式工作。我相信,在这种情况下,仅在 CustomerNo 上添加一个额外的索引会是更安全的方法吗?
  • 这完全取决于优化器是否会在连接之前推送过滤器。一个半盲的猜测是在连接列和 where 谓词上创建单独的索引。 (顺便说一句,您也可以在测试环境中运行这些查询。只需在那里运行早上的批处理)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-08
  • 1970-01-01
  • 2021-11-13
  • 1970-01-01
  • 2021-03-09
  • 2013-05-30
相关资源
最近更新 更多