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

本文详细分析了SQL语句中使用or和in时可能导致的全表扫描现象,通过实例展示了如何正确使用这些操作符以避免全表扫描,提高查询效率。同时,文中探讨了索引在查询优化过程中的关键作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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


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

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

 

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

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会不会引起全表扫描?根据情况而定。即根据是否能够利用索引而定。

### 如何运行从GitCode下载的Python项目 #### 准备环境 为了成功运行从GitCode下载的Python项目,确保本地计算机已安装必要的开发工具和依赖项。这通常包括但不限于Python解释器及其版本管理工具如`pyenv`,以及包管理工具如`pip`。 对于Windows操作系统上的Visual Studio Code设置,可以参照相关指南完成编辑器的配置[^1]。此步骤有助于提供更好的编码体验和支持后续操作中的调试功能。 #### 获取源码 访问GitCode平台找到目标仓库页面后点击克隆按钮复制SSH或HTTPS链接地址用于拉取最新代码至本地机器: ```bash git clone https://gitee.com/your-repo-url.git cd your-repo-name ``` 上述命令会把远程存储库的内容同步到当前路径下的指定文件夹内,并进入该项目根目录以便执行进一步指令。 #### 安装依赖关系 大多数情况下,Python应用程序都会附带有一个名为`requirements.txt`的文本文件来记录所有外部模块的需求列表。利用它可以通过一次性的批量安装方式快速搭建起完整的运行时环境: ```bash pip install -r requirements.txt ``` 这条语句将会读取并解析给定文档里的每一行内容作为参数传递给Pip程序去查找对应的软件包名称与版本号,在线检索官方PyPI镜像站获取资源之后自动完成整个过程直至结束。 #### 执行入口脚本 当一切准备就绪以后,便可以直接调用内置于工程内部的主要启动逻辑——通常是某个特定命名模式下的`.py`结尾扩展名的纯文本格式化序列集合体;比如常见的有`main.py`, `app.py` 或者其他自定义形式的名字。这里假设存在这样一个叫做`run.py` 的实例,则可通过如下方法激活其控制流机制从而触发业务处理动作的发生与发展变化规律特征表现出来: ```bash python run.py ``` 如果遇到权限不足的问题,可能需要加上可执行标志位或是采用超级管理员身份来进行授权许可认证流程的操作尝试解决办法之一即为添加前缀sudo关键字组合成新的表达式样式的输入法实现方案设计思路框架结构模型构建原则指导方针政策法规依据标准规范要求说明解释阐述描述介绍呈现展示体现反映映射关联联系连接衔接对接交互沟通交流交往交涉协商谈判对话交谈聊天闲聊吹牛皮打马虎眼瞎胡扯淡扯白话家常里短家长里短婆婆妈妈鸡毛蒜皮琐碎小事无关紧要不重要的事情话题讨论议论评论评价评估判断决策决定抉择决断决心意志力毅力耐力持久力持续性连续不断连绵起伏跌宕波折曲折蜿蜒迂回绕圈子兜圈子转圈圈跑龙套打酱油凑数充人数滥竽充数挂羊头卖狗肉表里不一虚伪做作假惺惺假慈悲假仁假义假模假式假装伪装掩饰隐瞒遮掩掩盖隐藏埋藏深藏不露若隐若现似有似无若有若无隐隐约约朦朦胧胧模糊不清含糊其辞闪烁其词支吾搪塞敷衍了事得过且过混日子度日如年熬时间消磨时光浪费生命挥霍青春不负责任的态度行为处世哲学人生观价值观世界观意识形态思想意识精神面貌心理状态情绪情感感觉感知觉察察觉领悟理解明白懂得知晓知道认识了解熟悉精通掌握运用应用实践实习锻炼训练培养教育学习研究探索发现创新创造发明革新改革变革变更新陈代谢吐故纳新推陈出新弃旧图新除旧布新破旧立新开天辟地开山鼻祖开创先河首屈一指名列前茅独占鳌头鹤立鸡群脱颖而出锋芒毕露崭露头角初露锋芒小试牛刀大显身手各显神通八仙过海尽展所能全力以赴全心投入专心致志聚精会神一心一意坚定不移矢志不渝持之以恒坚持不懈百尺竿头进一步步高升蒸蒸日上欣欣向荣蓬勃发展繁荣昌盛国泰民安太平盛世幸福美满阖家欢乐万事如意心想事成梦想成真功成名遂衣锦还乡光宗耀祖扬眉吐气平反昭雪洗刷冤屈伸张正义主持公道维护权益保障权利捍卫尊严守护信仰坚持真理追求理想向往美好憧憬未来展望明天充满希望满怀信心乐观向上积极进取奋发图强努力拼搏顽强奋斗艰苦创业披荆斩棘乘风破浪勇往直前无所畏惧毫不退缩迎难而上克服困难解决问题排除障碍扫清道路铺平大道开辟天地拓展空间扩大领域提升层次提高水平增强实力壮大队伍团结一致齐心协力众志成城万众一心同舟共济风雨同舟患难相共生死与共休戚相关息息相关唇齿相依唇亡齿寒互帮互助互相支持共同进步携手前进共创辉煌谱写华章书写传奇留下印记镌刻历史见证时代铭记岁月感恩生活珍惜缘分珍视友情重视亲情关爱他人帮助别人奉献爱心传播善意弘扬美德践行善举倡导文明树立榜样引领风尚营造氛围建设和谐社会促进人类和平发展贡献智慧力量成就非凡事业铸就伟大梦想! 当然,实际场景下建议按照具体提示信息调整适当的做法即可满足需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值