在网上看一些文章的时候,发现好几次下面这样的话:

如果经常需要同时对两个字段进行AND查询,那么使用两个单独索引不如建立一个复合索引,因为两个单独索引通常数据库只能使用其中一个,而使用复合索引因为索引本身就对应到两个字段上的,效率会有很大提高。

但是,往往都没有说为什么?想知道以下问题:
1、是不是在任何情况下数据库查询一次只会使用到一个索引?
2、如果不是,那么什么情况下只会使用一个索引?
3、那分别是什么造成上面的查询索引使用问题呢?

与其说是“数据库查询只能用到一个索引”,倒不是说是 和全表扫描/只使用一个索引的速度比起来,去分析两个索引二叉树更加耗费时间,所以绝大多数情况下数据库都是是用一个索引。
如这条语句:

select count(1) from table1 where column1 = 1 and column2 = 'foo' and column3 = 'bar'

我们来想象一下当数据库有N个索引并且查询中分别都要用上他们的情况:
查询优化器(用大白话说就是生成执行计划的那个东西)需要进行N次主二叉树查找[这里主二叉树的意思是最外层的索引节点],此处的查找流程大概如下:
查出第一条column1主二叉树等于1的值,然后去第二条column2主二叉树查出foo的值并且当前行的coumn1必须等于1,最后去column主二叉树查找bar的值并且column1必须等于1和column2必须等于foo。
如果这样的流程被查询优化器执行一遍,就算不死也半条命了,查询优化器可等不及把以上计划都执行一遍,贪婪算法(最近邻居算法)可不允许这种情况的发生,所以当遇到以下语句的时候,数据库只要用到第一个筛选列的索引(column1),就会直接去进行表扫描了。

select count(1) from table1 where column1 = 1 and column2 = 'foo' and column3 = 'bar'

所以与其说是数据库只支持一条查询语句只使用一个索引,倒不如说N条独立索引同时在一条语句使用的消耗比只使用一个索引还要慢。
所以如上条的情况,最佳推荐是使用index(column1,column2,column3) 这种联合索引,此联合索引可以把b+tree结构的优势发挥得淋漓尽致:
一条主二叉树(column=1),查询到column=1节点后基于当前节点进行二级二叉树column2=foo的查询,在二级二叉树查询到column2=foo后,去三级二叉树column3=bar查找。

来源:https://segmentfault.com/q/1010000003880137

数据库中查询记录时是否每次只能使用一个索引?相关推荐

  1. rowspan 动态变化_php – 从数据库中获取记录时的动态rowspan

    抱歉我的英语不好: 在这里,我回答了这个问题 How to show data from database with dynamic rowspan.再次让我试着回答这个问题.首先,以免我们在mysq ...

  2. Oracle数据库中有关记录个数的查询

    一.查询表中全部的记录个数 可用两种方法,一种是在oracle的系统表中统计,另一种需要写存储过程统计,方法分别如下. 1.系统表中统计: SELECT sum(num_rows) FROM user ...

  3. mysql 查询不为0的数据_查询数据库中所有记录总数不为0的数据表名称

    [如何查询postgreSQL 里面某个数据库中所有用户定义的数据表的名字@forandever 2011-11-131.通过命令行查询\d 数据库  -- 得到所有表的名字\d 表名  -- 得到表 ...

  4. 不同数据库中查询前几条记录的用法(SQL Server/Oracle/Postgresql)

    SQL在不同数据库中查询前几条记录的用法分类 1. orACLE Select * FROM TABLE1 Where ROWNUM<=N 2. INFORMIX Select FIRST N ...

  5. php如何查询数据是否存在,PHP判断数据库中的记录是否存在的方法,php数据库_PHP教程...

    PHP判断数据库中的记录是否存在的方法,php数据库 本文实例讲述了PHP判断数据库中的记录是否存在的方法.分享给大家供大家参考. 具体实现代码如下: 复制代码 代码如下: $sql="se ...

  6. oracle查询记录插入,我应该使用哪种查询语法在Oracle数据库中插入记录?

    我是一个初学者,试图用C#创建一个简单的程序来插入和更新Oracle数据库中的记录.我已经成功地连接到数据库,但是我的SQL语句出现异常,该异常指出不支持(?)符号.为什么会出现此异常,该如何解决? ...

  7. flask查询mysql数据展示_flask再学习-思考之怎么从数据库中查询数据在页面展示!...

    看别人视频觉得很简单,要自己做蒙蔽了!这样子.NO! 1. 流程: 首先要有和数据库连接的驱动!一般有PYMySQL mysqlclient 等 使用扩展Flask-SQLAlchemy 获得orm对 ...

  8. mysql查询计算机系信息_在学生管理数据库中查询通信系和计算机系的所有教师信息...

    在学生管理数据库中查询通信系和计算机系的所有教师信息 答:select * from 教师 where 系部代码 in(select 系部代码 from 系部 where 系部名称 in('通信系', ...

  9. ssm java编程遇到从数据库中查询的时间与存储时间不一致

    ssm java编程遇到从数据库中查询的时间与存储时间不一致 推荐先去看这篇文章: java编程中遇到的时区与时间问题总结 http://blog.csdn.net/yeahwell/article/ ...

最新文章

  1. AI 真的能够理解人类语言吗?
  2. AntiXSS - 支持Html同时防止XSS攻击
  3. C++ Opengl WaveFlag(飘扬的旗帜)源码
  4. python 内存数据库下载,Python 文件存储和数据库
  5. python中如何标识语句块_如何用python在一个块中编写多个try语句?
  6. 修改tomcat端口号、编码
  7. 第6章 类型和成员基础
  8. Word如何添加楷体_GB2312
  9. JavaScript(二)数据类型(二)
  10. oracle erase,Arc SDE forOracle实现erase空间分析计算
  11. html中加载gif图片,使用CSS3实现动态加载gif图片的效果
  12. 5G关键技术与系统演进pdf
  13. Win10修修补补日记:Win10周年更新再出BUG 淡定
  14. 跨境电商属于外贸吗,Starday跨境电商靠谱吗?
  15. 白炽灯护眼还是LED护眼?盘点专业护眼的LED护眼灯
  16. C Primer Plus 第11章_字符串和字符串函数_代码和练习题
  17. 说明书丨ReliaTech艾美捷大鼠羧肽酶-B
  18. Orecal日期与系统日期相减
  19. 优秀的股指期货策略,期货反向跟单。
  20. 过度的躺平和过度的努力一样,都是透支

热门文章

  1. java实现一个gui面板_JAVA GUI自定义JPanel画板背景
  2. 24.volatile关键字的作用、volatile原理、可见性、内存屏障、volatile性能、transient
  3. 6.组函数(avg(),sum(),max(),min(),count())、多行函数,分组数据(group by,求各部门的平均工资),分组过滤(having和where),sql优化
  4. 最小二乘法矩阵微分偏导法证明
  5. 服务器配置文件salt,saltstack 配置文件详解
  6. 中如何使用echart_jQueryEasyUI中的拖拽事件如何使用
  7. 摄影中的色温和白平衡及其二者关系的全面详解
  8. Homepage Machine Learning Algorithm 浅谈深度学习中的激活函数 - The Activation Function in Deep Learning
  9. BM15 删除有序链表中重复的元素-I
  10. 快速排序的C++实现(利用二分分治法)