ehxz 发表于 2008-2-2 15:37:50

SQL Server索引(9)-Indexing for OR

  我们仍然使用http://www.dbacn.com/dbabbs/viewthread.php?tid=528&extra=page%3D1中的 member 表,这时候,这个表的索引如下:
  名字描述列

  member_corporation_linknonclustered located on PRIMARYcorp_no

  member_identclustered, unique, primary key located on PRIMARYmember_no

  member_region_linknonclustered located on PRIMARYregion_no

  MemberFirstNamenonclustered located on PRIMARYfirstname

  MemberLastNamenonclustered located on PRIMARYlastname

  我们执行下面的查询

  SELECT m.LastName, m.FirstName, m.Region_No

  FROM dbo.Member AS m

  WHERE m.FirstName = 'Kimberly'

  OR m.LastName = 'Tripp'

  go

  我们用另外一个SQL来模拟 SQL 的执行计划,就是下面的语句:

  我们会看到上面语句跟下面的语句基本一样,只是一个是 Key Lookup ,一个是 Clustered Index Seek。 这里由于是模拟情况,可以认为是一样的。

  select m.LastName, m.FirstName, m.Region_No

  FROM dbo.Member AS m with(index(member_ident)),

  (

  select ww.Member_No from (

  select Member_No from dbo.Member where FirstName = 'Kimberly'

  union all

  select Member_No from dbo.Member where LastName = 'Tripp'

  ) ww

  group by ww.Member_No

  )

  n

  where m.Member_No = n.Member_No

  go

  这两个查询的扫描计数均是 2,逻辑读取均是 10 次。

  他们俩个的执行计划如下图,点击看大图:


  知识点小结:

  OR 会做什么?

  将多个结果集集合起来,上图中,使用 Merge Join(Concatenation)把数据汇集起来。

  保证每一个row只出现一回,上图中,使用Stream Aggregate(Aggregate)进行排重。

  上面的例子中,我们用 union 来演示 or的情况。 OR和UNION相似。不同之处如下:

  OR 根据 row’s unique identifier (RID or Clustering Key) 去掉副本

  UNION 根据 SELECT list 去掉副本

  UNION ALL 不去除副本

  OR 的一个简单应用就是 In 关键字。

  如果有In搜索关键字的对应索引。则系统会使用这个索引。

  如果没有,则遍历(表遍历或者索引遍历)是高性能的选择。
页: [1]
查看完整版本: SQL Server索引(9)-Indexing for OR