广告
返回顶部
首页 > 资讯 > 数据库 >Mysql索引的使用-组合索引+跳跃条件
  • 367
分享到

Mysql索引的使用-组合索引+跳跃条件

2024-04-02 19:04:59 367人浏览 泡泡鱼
摘要

关于Mysql组合索引的使用,官方对下面的例子的说法是可以使用索引:KEY(key_part1,key_part2,key_part3)select .... from table wher

关于Mysql组合索引的使用,官方对下面的例子的说法是可以使用索引:

KEY(key_part1,key_part2,key_part3)
select .... from table where key_part1='xxx' and key_part3='yyy';

mysql的执行计划看,确实也是使用索引;

但在实际的优化过程中,我们只是简单的关注是否使用了这个索引是不够的。

[@more@]

我们需要关注的是:
对key_part3这个关键字过滤的时候,是否用到了索引?

下面我们来创建一个例子:
CREATE TABLE `im_message_201001_12` (
`msg_id` bigint(20) NOT NULL default '0',
`time` datetime NOT NULL,
`owner` varchar(64) collate latin1_bin NOT NULL,
`other` varchar(64) collate latin1_bin NOT NULL,
`content` varchar(8000) collate latin1_bin default NULL,
PRIMARY KEY (`msg_id`),
KEY `im_msg_own_oth_tim_ind` (`owner`,`other`,`time`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;

查询语句:
select count(distinct concat('ab',content)) dis ,count(*) all from im_message_201001_12
where
owner='huaniaoyuchong83'
and time between '2010-01-01 00:00:00' and '2010-02-01 00:00:00' ;

我们看到,查询的条件,对索引来说是跳跃的。
这对oracle来说并不是难事。sql优化器会在索引里完成对time字段的过滤。
用HINT: 可以来辅助。
但对MYSQL来说,你可能并不知道,是什么时候对time字段进行过滤的。
当然我们希望是通过索引来过滤TIME字段。这样最后回表的次数就会少一些。

测试过程中,我们通过观察MYSQL的Innodb_buffer_pool_read_requests(逻辑读)变量的变化,来推测结果。
注意以下查询过程中,条件time的变化,以及变量Innodb_buffer_pool_read_requests的变化


#######测试环境:
OS:RHEL 4.7 X86_64
MYSQL 5.0.51a / 5.1.40

请在开始下面测试前,运行:
select count(distinct concat('c',content)),count(*) from im_message_201001_11 where owner='huaniaoyuchong83' ;
以让所有结果都在CACHE里;


#######开始第一次测试
show session status like 'Innodb_buffer_pool_read_requests';
+----------------------------------+-----------+
| Variable_name | Value |
+----------------------------------+-----------+
| Innodb_buffer_pool_read_requests | 136566076 |
+----------------------------------+-----------+
1 row in set (0.02 sec)

select count(distinct concat('c',content)),count(*) from im_message_201001_11 where owner='huaniaoyuchong83' and time between '2010-01-01 00:00:00' and '2010-02-01 00:00:00' ;

+-------------------------------------+----------+
| count(distinct concat('c',content)) | count(*) |
+-------------------------------------+----------+
| 35644 | 44397 |
+-------------------------------------+----------+
1 row in set (1.40 sec)

show session status like 'Innodb_buffer_pool_read_requests';
+----------------------------------+-----------+
| Variable_name | Value |
+----------------------------------+-----------+
| Innodb_buffer_pool_read_requests | 136742193 |
+----------------------------------+-----------+
1 row in set (0.02 sec)

select 136742193-136566076 ;
+---------------------+
| 136742193-136566076 |
+---------------------+
| 176117 |
+---------------------+
1 row in set (0.00 sec)


#######开始第二次测试
show session status like 'Innodb_buffer_pool_read_requests';
+----------------------------------+-----------+
| Variable_name | Value |
+----------------------------------+-----------+
| Innodb_buffer_pool_read_requests | 136742194 |
+----------------------------------+-----------+
1 row in set (0.02 sec)

select count(distinct concat('c',content)),count(*) from im_message_201001_11 where owner='huaniaoyuchong83' and time between '2010-01-01 00:00:00' and '2010-01-05 00:00:00' ;

+-------------------------------------+----------+
| count(distinct concat('c',content)) | count(*) |
+-------------------------------------+----------+
| 3679 | 4097 |
+-------------------------------------+----------+
1 row in set (0.74 sec)

show session status like 'Innodb_buffer_pool_read_requests';
+----------------------------------+-----------+
| Variable_name | Value |
+----------------------------------+-----------+
| Innodb_buffer_pool_read_requests | 136916032 |
+----------------------------------+-----------+
1 row in set (0.01 sec)

select 136916032-136742194;
+---------------------+
| 136916032-136742194 |
+---------------------+
| 173838 |
+---------------------+
1 row in set (0.00 sec)

#######开始第三次测试


show session status like 'Innodb_buffer_pool_read_requests';
+----------------------------------+-----------+
| Variable_name | Value |
+----------------------------------+-----------+
| Innodb_buffer_pool_read_requests | 136916033 |
+----------------------------------+-----------+
1 row in set (0.01 sec)

select count(distinct concat('c',content)),count(*) from im_message_201001_11 where owner='huaniaoyuchong83' and time between '2010-01-01 00:00:00' and '2010-01-01 00:00:00' ;

+-------------------------------------+----------+
| count(distinct concat('c',content)) | count(*) |
+-------------------------------------+----------+
| 0 | 0 |
+-------------------------------------+----------+
1 row in set (0.85 sec)

show session status like 'Innodb_buffer_pool_read_requests';
+----------------------------------+-----------+
| Variable_name | Value |
+----------------------------------+-----------+
| Innodb_buffer_pool_read_requests | 137086323 |
+----------------------------------+-----------+
1 row in set (0.01 sec)

select 137086323-136916033;
+---------------------+
| 137086323-136916033 |
+---------------------+
| 170290 |
+---------------------+
1 row in set (0.00 sec)


#######开始第四次测试

show session status like 'Innodb_buffer_pool_read_requests';
+----------------------------------+-----------+
| Variable_name | Value |
+----------------------------------+-----------+
| Innodb_buffer_pool_read_requests | 137086324 |
+----------------------------------+-----------+
1 row in set (0.02 sec)

select count(*) from im_message_201001_11 where owner='huaniaoyuchong83' and time between '2010-01-01 00:00:00' and '2010-02-01 00:00:00' ;
+----------+
| count(*) |
+----------+
| 44397 |
+----------+
1 row in set (0.05 sec)

show session status like 'Innodb_buffer_pool_read_requests';
+----------------------------------+-----------+
| Variable_name | Value |
+----------------------------------+-----------+
| Innodb_buffer_pool_read_requests | 137092204 |
+----------------------------------+-----------+
1 row in set (0.01 sec)

select 137092204-137086324 ;
+---------------------+
| 137092204-137086324 |
+---------------------+
| 5880 |
+---------------------+
1 row in set (0.00 sec)

#######开始第五次测试

show session status like 'Innodb_buffer_pool_read_requests';
+----------------------------------+-----------+
| Variable_name | Value |
+----------------------------------+-----------+
| Innodb_buffer_pool_read_requests | 137092205 |
+----------------------------------+-----------+
1 row in set (0.01 sec)

select count(*) from im_message_201001_11 where owner='huaniaoyuchong83' ;
+----------+
| count(*) |
+----------+
| 44397 |
+----------+
1 row in set (0.04 sec)

show session status like 'Innodb_buffer_pool_read_requests';
+----------------------------------+-----------+
| Variable_name | Value |
+----------------------------------+-----------+
| Innodb_buffer_pool_read_requests | 137098085 |
+----------------------------------+-----------+
1 row in set (0.01 sec)

select 137098085-137092205 ;
+---------------------+
| 137098085-137092205 |
+---------------------+
| 5880 |
+---------------------+
1 row in set (0.00 sec)


#######开始第六次测试

show session status like 'Innodb_buffer_pool_read_requests';
+----------------------------------+-----------+
| Variable_name | Value |
+----------------------------------+-----------+
| Innodb_buffer_pool_read_requests | 137098131 |
+----------------------------------+-----------+
1 row in set (0.02 sec)

select count(*) from im_message_201001_11 where owner='huaniaoyuchong83' and time between '2010-01-01 00:00:00' and '2010-01-05 00:00:00' ;
+----------+
| count(*) |
+----------+
| 4097 |
+----------+
1 row in set (0.05 sec)

show session status like 'Innodb_buffer_pool_read_requests';
+----------------------------------+-----------+
| Variable_name | Value |
+----------------------------------+-----------+
| Innodb_buffer_pool_read_requests | 137104011 |
+----------------------------------+-----------+
1 row in set (0.01 sec)

select 137104011-137098131;
+---------------------+
| 137104011-137098131 |
+---------------------+
| 5880 |
+---------------------+
1 row in set (0.00 sec)

####### 分析结果

前三次查询,从索引检索后需要回表:
time 结果行数 逻辑读
30天 44397 176117
5天 4097 173838
1天 0 170290

后三次查询,从索引检索后不需要回表
time 结果行数 逻辑读
30天 44397 5880
无time条件 44397 5880
5天 4097 5880

从数据来看,
select count(*) 这样的查询,有或者没有time条件,逻辑读是一样,都不用回表。
这里也说明这种情况MYSQL是用索引进行time字段的过滤。

select count(distinct concat('c',content)),count(*), 这样的查询,用到了索引以外的字段,是必需回表的。
但通过逻辑读发现,不管查询结果是多少行,逻辑读都差不多,在17W左右。
特别是结果行为0时,如果是通过索引过滤time,那么逻辑读应该接近5900,而不是17W。
这也说明,这种情况下,MYSQL没有使用索引来对TIME字段进行过滤;

所以MYSQL对相同WHERE条件的查询,还采用了不同的优化程序;但MS这个优化有点问题。


对这样的索引,需要优化,可以。 调整索引顺序(`owner`,`time`,`other`)。
但是这仅仅是对一个SQL的优化。
你还要考虑到系统里还有很多其他类似的SQL需要用到这个索引。 所以在优化时,需要评估所有的SQL。

您可能感兴趣的文档:

--结束END--

本文标题: Mysql索引的使用-组合索引+跳跃条件

本文链接: https://www.lsjlt.com/news/48397.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Mysql索引的使用-组合索引+跳跃条件
    关于MYSQL组合索引的使用,官方对下面的例子的说法是可以使用索引:KEY(key_part1,key_part2,key_part3)select .... from table wher...
    99+
    2022-10-18
  • mysql 联合索引生效的条件及索引失效的条件
    目录1.联合索引失效的条件 2.索引失效的条件 1.联合索引失效的条件 联合索引又叫复合索引。两个或更多个列上的索引被称作复合索引。 对于复合索引:Mysql从左到右的使用索引中的...
    99+
    2022-11-12
  • mysql中联合索引生效的条件及索引失效的条件是什么
    这篇文章主要介绍mysql中联合索引生效的条件及索引失效的条件是什么,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1.联合索引失效的条件联合索引又叫复合索引。两个或更多个列上的索引被称作复合索引。对于复合索引:Mys...
    99+
    2023-06-25
  • mysql聚集索引、辅助索引、覆盖索引、联合索引的使用
    目录聚集索引(Clustered Index)辅助索引(Secondary Index)覆盖索引(Covering index)联合索引《MySQL技术内幕 InnoDB存储引擎》学...
    99+
    2022-11-13
  • MySQL单列索引和组合索引的区别
    这篇文章主要讲解了“MySQL单列索引和组合索引的区别”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“MySQL单列索引和组合索引的区别”吧!  MySQL单...
    99+
    2022-10-18
  • 复合索引使用的先决条件
    PS:懒得重新编辑图片了,直接把我从51上的日志拷过来了。背景:今天,接到一个项目的项目经理电话,告之说生产环境有几个查询超级慢,就是查询单张表的数据,查询条件也很简单,但是加了索引以后并没有走索引,依然还...
    99+
    2022-10-18
  • MySQL避免索引列使用 OR 条件
    这个亏已经吃过很多次了,在开发以前的sql代码里面,许多以 or 作为where条件的查询,甚至更新。这里举例来说明使用 or 的弊端,以及改进办法。 select f_crm_id fro...
    99+
    2022-05-25
    mysql
  • mysql 索引合并的使用
    索引合并是mysql底层为我们提供的智能算法。了解索引合并的算法,有助于我们更好的创建索引。 索引合并是通过多个range类型的扫描并且合并它们的结果集来检索行的。仅合并来自单个表...
    99+
    2022-11-12
  • MySQL组合索引(多列索引)使用与优化案例详解
    目录1、多列索引2、测试案例及过程2.1 创建一个测试数据库和数据表2.2 添加两个单列索引2.3 查询一条数据利用到两个列的索引2.4 查看执行计划2.5 然后删除以上索引,添加多列索引2.6 再次查询3、多列索引的使...
    99+
    2022-07-04
    mysql组合索引使用 mysql索引
  • MySQL单列索引和联合索引的用法
    本篇内容主要讲解“MySQL单列索引和联合索引的用法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“MySQL单列索引和联合索引的用法”吧!本文通过一个案例,介绍...
    99+
    2022-10-18
  • mysql多条件查询会使用索引吗
    mysql多条件查询会使用索引,取决因素有:1、索引的选择性,指索引中具有唯一或较小重复值的比例;2、索引的覆盖度,指索引中包含了查询所需的所有列,从而避免了对实际数据行的访问,提高查询性能;3、查询的顺序和条件结合,根据查询的具体情况进行...
    99+
    2023-07-25
  • MySQL 使用 OR 条件导致索引失效
    背景:需要根据工号或英文名带出中文名,但数据量过大,导致响应时间过长 查询工号为 x20230506 或者英文名是 codeporter 的用户信息 select * from user_test where login...
    99+
    2023-09-05
    mysql 性能优化
  • 【转】MySQL合理使用索引
    索引可以说是数据库中的一个大心脏了,如果说一个数据库少了索引,那么数据库本身存在的意义就不大了,和普通的文件没什么两样。所以说一个好的索引对数据库系统尤其重要,今天来说说MySQL索引,从细节和实际业务的角度看看在MySQL中B+树索引好...
    99+
    2016-03-25
    【转】MySQL合理使用索引
  • MySQL中的组合索引与单列索引的区别有哪些
    本篇内容介绍了“MySQL中的组合索引与单列索引的区别有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!...
    99+
    2022-10-18
  • MySQL联合索引怎么使用
    MySQL联合索引是指在一个表中同时使用多个列作为索引的方式,可以提高查询效率。使用方法如下: 创建联合索引: ALTER TA...
    99+
    2023-10-27
    MySQL
  • mysql联合索引的使用规则
    联合索引又叫复合索引。对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。例如索引是key index (a,b,c). 可以支...
    99+
    2022-11-12
  • mysql索引合并的说明和使用
    本篇内容介绍了“mysql索引合并的说明和使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!什么是索引合并...
    99+
    2022-10-18
  • MySQL查询条件中in会用到索引吗
    当用人问你MySQL 查询条件中 in 会不会用到索引,你该怎么回答? 答案:可能会用到索引 动手来测试下 1.创建一张表,给字段port建立索引 CREATE TABLE `pre_re...
    99+
    2022-10-18
  • 如何查询sql语句的条件字段是否使用了索引以及跳过索引的几种情况
    今天执行通过时间范围查询订单数量的sql时,想看看该时间字段是否走了索引,发现一个很有意思的问题. 首先说一下查询是否使用了索引的方法 通过explain来查看,即将explain放在查询的sql前面 explain SELECT...
    99+
    2021-09-24
    如何查询sql语句的条件字段是否使用了索引以及跳过索引的几种情况 数据库入门 数据库基础教程 数据库 mysql
  • Pytorch 使用tensor特定条件判断索引
    torch.where() 用于将两个broadcastable的tensor组合成新的tensor,类似于c++中的三元操作符“?:” 区别于python num...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作