为or、in平反——or、in到底能不能利用索引?

简介:   先说一个笑话,作为开场白。俺也换换风格试一试,呵呵。   在以前,有三个书生赶考,在路上遇到了一个算命先生,于是就问算命先生:我们三个人赶考,结果如何呀?算命先生伸出来了一个手指头(食指)。

 

  先说一个笑话,作为开场白。俺也换换风格试一试,呵呵。


  在以前,有三个书生赶考,在路上遇到了一个算命先生,于是就问算命先生:我们三个人赶考,结果如何呀?算命先生伸出来了一个手指头(食指)。三个书生赶考的结果是,有一个人考中了。三人一想呀,这个挂算的对呀,有一个人考中了嘛。

  其实“一个手指头”是很模糊的,很忽悠人的。有各种各样的解释,比如:一个人考中;一个人没考中;一起考中了;一起没考中。这种模棱两可的说法完全没有指导意义!

 

  好了书归正传,说说数据库方面的事情。在网上看到了几种说法,我们一起来分析一下说的到底对不对,是不是准确的,有没有歧义,会不会误导大家。

1、 or会引起全表扫面。
2、 in会引起全表扫描。
3、 in会引起全表扫描,并且和or等效。
4、 or语句使用不当会引起全表扫描。

 

  为了避免一些误会,同时也是缩小讨论范围,所以先解释一个名词和说一下前提条件。

名词解释:
全表扫描在数据库中,对无索引的表进行查询一般称为全表扫描。全表扫描是数据库服务器用来搜寻表的每一条记录的过程,直到所有符合给定条件的记录返回为止。
引自:http://baike.baidu.com/view/2010124.htm?fr=ala0_1_1

 

前提条件


  数据库:SQL Server2000 + sp4 (注意:一定要安装sp4补丁包,如果未安装任何补丁包可能执行计划会和安装sp4的不一致)

其他数据库没有研究,所以在这里就不讨论了。

 

 

  好了,名词解释和前提条件都说好了,我们开始讨论吧。

 

  第四个说法是我用google搜索出来的,说的很明确。or“使用不当”才会引起全表扫描,那么使用得当的话,显然是可以避免全表扫描的。文章的例子也说的很明确。http://www.zbitedu.com/?action-viewthread-tid-39219

 

  在这里不得不赞扬一下google的强大,google搜索出来的结构都是明确的,而且可以把明确的排在第一位。而baidu就不管三七二十一,管你对不对、是否明确,全都收录进来,然后你自己去分析、思考吧。Bs baidu 一下。


  而前三总说法就很不明确,和算命先生的那句话有的一拼。即没有明确的说“一定”会引起全表扫描,也没有说有没有例外,含含糊糊,极易误导人。试问:您有没有下意识的加上了一个定语“一定”(or一定会引起全表扫描)呢?如果您没有加上“一定”这个定语的话,那么您有没有想过是否有反例?

 

  如果没有反例的话,那么就加上“一定”就是正确的,那么原话为什么不加上?

  如果有反例的话,那么原话就完全没有交代清楚。

  所以有没有反例,这就是一个很不明确,很误导人的地方。

 

  当然了——in和or是等效的——这句话我是认同的。in和or确实是等效的,数据库会把in转换成or的形式。

 

 

开始分析


  以一个Northwind数据库的Employees表 为例(这是SQL Server2000里自带的数据库),分析几种SQL语句的执行计划。

 

SELECT   *
FROM  Employees
WHERE  (EmployeeID  IN  ( 2 4 5 ))

SELECT   *
FROM  Employees
WHERE  EmployeeID  =   2   or  EmployeeID  =    4   or  EmployeeID  =    5

 

 

 

  这两个SQL语句的执行结果是一致的,执行计划也是一致的。我们来看看EmployeeID字段在有无索引,有什么类型的索引的情况下,执行计划都是什么样子的

 

1、 EmployeeID不是主键(没有聚集索引和非聚集索引)
 


 

  从执行计划里可以明确的看出来,在没有索引的情况下,确实引起了全表扫描。(请不要着急下结论,还有两种情况没有看呢。)


2、 是主键(聚集索引)

 

  当是主键,并且是聚集索引的情况下,执行计划发生了变化,避免了全表扫描。

 

3、 不是主键,但是设置了非聚集索引

 

 

  这回执行计划又发生了变化,不过依然没有引起全表扫描,只是增加了一个步骤(使用标签)

 

  本来想看看只有主键,但是主键字段不设置索引(聚集和非聚集)的情况下,执行计划是什么样子的,但是发现一个小问题,我不知道怎么让设置成主键的字段没有任何索引?企业管理器里是把主键和聚集索引强行绑定到一起了,把一个字段设置成主键,同时也把聚集索引设置给了这个字段。目前我是没发现怎么把这个主键的索引给去掉。也许应该用SQL语句的方式给表设置主键吧。这个就先不研究了。

 

  总结:in和or会不会引起全表扫描?根据情况而定。即根据是否能够利用索引而定。


 

相关文章
|
6月前
|
索引
索引
索引。
37 0
|
6月前
|
存储 关系型数据库 MySQL
了解和认识索引
了解和认识索引 。
37 0
|
6月前
|
存储 SQL 关系型数据库
索引
索引(在MySQL中也叫做“键(key)”)是存储引擎用于快速找到记录的一种数据结构。 索引是快速搜索的关键。MySQL索引的建立对于MySQL的高效运行是很重要的。对于少量的数据,没有合适的索引影响不是很大,但是,当随着数据量的增加,性能会急剧下降。如果对多列进行索引(组合索引),列的顺序非常重要,MySQL仅能对索引最左边的前缀进行有效的查找。
20 0
|
6月前
|
关系型数据库 MySQL 索引
索引(2)
索引(2)。
15 0
|
6月前
|
关系型数据库 MySQL 数据库
了解和认识索引
了解和认识索引。
25 0
|
10月前
|
数据库 索引
请注意这些情况下,你的索引会不生效!
数据库性能优化是确保系统高效运行的关键要素之一。而索引作为提升数据库查询性能的重要工具,在大部分情况下都能发挥显著的作用。然而,在某些情况下,索引可能会失效或不起作用,导致查询性能下降,甚至引发性能瓶颈。
|
10月前
|
索引
表索引——唯一索引
表索引——唯一索引
|
10月前
|
数据库 索引
表索引——普通索引
表索引——普通索引
|
存储 SQL 关系型数据库
【名词解释与区分】聚集索引、非聚集索引、主键索引、唯一索引、普通索引、前缀索引、单列索引、组合索引、全文索引、覆盖索引
【名词解释与区分】聚集索引、非聚集索引、主键索引、唯一索引、普通索引、前缀索引、单列索引、组合索引、全文索引、覆盖索引
220 1
【名词解释与区分】聚集索引、非聚集索引、主键索引、唯一索引、普通索引、前缀索引、单列索引、组合索引、全文索引、覆盖索引
|
存储 缓存 自然语言处理
正排索引
介绍ElasticSearch相关正排索引

热门文章

最新文章