mysql 复合索引 in,MySQL复合索引比主键索引还快,为什么?
存储引擎:innodb
题目如下:
create table t(
id primary,
ver int,
content varchar(3000),
intro varchar(3000)
) engine innodb charset utf8;
表有10000条数据,按如下条件查询:
select id from t order by id #慢
select id from t order by id,ver #快
为什么?
实验如下:
创建一个innodb引擎的表:
create table smth(
id int(11) not null default '0',
ver int(11) default null,
content varchar(3000) default null,
intro varchar(3000) default null,
primary key(id),
key idver(id,ver)
)engine=innodb default charset=utf8;
通过php批量插入10000条数据:
input.php
set_time_limit(0);
$conn=mysql_connect('192.168.1.100','root','');
mysql_query('set names utf8',$conn)
mysql_query('use myopt',$conn);
for ($i=1;$i<=10000;$i++){
$sql=sprintf("insert into smth values(%d,%d,'%s','%s')",$i,rand(1,1000),str_repeat('中',3000),str_repeat('华',3000));
mysql_query($sql,$conn);
}
echo 'successfull';
?>
插入的数据如下图
mysql> use myopt;
Database changed
mysql> show tables;
+-----------------+
| Tables_in_myopt |
+-----------------+
| smth |
+-----------------+
1 row in set (0.00 sec)
mysql> select count(*) from smth;
+----------+
| count(*) |
+----------+
| 10000 |
+----------+
1 row in set (0.00 sec)
smth表已有10000条数据
打开profiling:
mysql> set profiling=1;
运行以下两条SQL语句:
select id from smth order by id #慢
select id from smth order by id,ver #快
查看两条SQL语句执行的时间:
mysql> show profiles;
+----------+------------+-------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+-------------------------------------+
| 1|0.57919600 | select id from smth order by id | #慢
| 2 |0.00014700| select id from smth order by id ver | #快
+----------+------------+-------------------------------------+
3 rows in set (0.00 sec)
两条语句的时间差了好几个数据级,这是为什么呢?
下面分析原因:
INNODB引擎,如果ID为主键,则会创建一个基于主键的聚簇索引,这个索引是以下面的形式而存在
innodb的索引下面就包含具体的表数据,找到了索引,就找到的具体的数据
但由于表中有两个大的字段varchar(30000),使得索引键值下面的数据太大,有可能一个索引键值对应一个数据页(16K)或多个数据页。这使得查询一个ID值将要扫描更多的数据页,才能取出ID值。
如下图:这个就是SQL语句select id from smthorder by id的情况。
对于select id from smth order by id ver的分析:
对ID,VER两个字段创建索引,返回ID的值,也就是说可以直接通过覆盖索引就可以找到所要的数据,不需要再回表查主键对应的数据,相当于在索引查数据,所有速度比上面的那个SQL要快
如下图:
如果存储引擎换成:MyISAM,结果会怎么样呢?
MYISAM索引的结构:
题目如下:
create table t(
id primary,
ver int,
content varchar(3000),
intro varchar(3000)
) engine innodb charset utf8;
表有10000条数据,按如下条件查询:
select id from t order by id
select id from t order by id,ver
为什么?
创建一个myisam引擎的表:
create table mysmth(
id int(11) not null default '0',
ver int(11) default null,
content varchar(3000) default null,
intro varchar(3000) default null,
primary key(id),
key idver(id,ver)
)engine=myisam default charset=utf8;
复制smth的数据到mysmth:
mysql> insert into mysmth select * from smth;
Query OK, 10000 rows affected (13.22 sec)
Records: 10000 Duplicates: 0 Warnings: 0
mysql> show tables;
+-----------------+
| Tables_in_myopt |
+-----------------+
| mysmth |
| smth |
+-----------------+
2 rows in set (0.00 sec)
mysql> select count(*) from mysmth;
+----------+
| count(*) |
+----------+
| 10000 |
+----------+
1 row in set (0.00 sec)
插入的数据如下:
实验测试:
打开profiling:
mysql> set profiling=1;
运行以下两条SQL语句:
select id from mysmth order by id
select id from mysmth order by id,ver
查看两条SQL语句执行的时间:
mysql> show profiles;
mysql> show profiles;
+----------+-------------+---------------------------------------+
| Query_ID | Duration | Query |
+----------+-------------+---------------------------------------+
| 10 | 0.00500125 |select id from mysmth order by id | #时间基本一样
| 11 | 0.00676950 |select id from mysmth order by id,ver | #时间基本一样
+----------+-------------+---------------------------------------+
2 rows in set (0.00 sec)
为什么?
这是因为myisam引擎中的索引与数据是分开的,索引的多少与数据不存在任何关联,由于是查询ID值,而且都是通过索引覆盖扫描,并没有找真正的数据,所有查询时间差不多
总结:
以上是由于存储引擎的特性决定了同一条SQL不同的执行时间
mysql 复合索引 in,MySQL复合索引比主键索引还快,为什么?相关推荐
- oracle索引未使用,oracle - 未使用主键索引 - SO中文参考 - www.soinside.com
首先,您应该考虑索引并不总是一个好主意. 如果Oracle必须从表中读取大多数数据,它将使用FULL TABLE SCAN,因为它比首先读取索引块然后再读取数据块更快.涉及太多的IO操作. 现在,回到 ...
- Mysql唯一索引、主键索引、联合索引
数据库索引都有哪些类型 普通索引 --加速查找 没有任何限制 主键索引 --加速查找+不能为空+不能重复 一般建表同时完成创建 一个表只能有一个主键 不允许控制 唯一索引 --加速查找+不能重复 索引 ...
- MySQL中的索引(主键索引)
MySQL中的索引(主键索引篇) 主键索引是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值.一般是在建表的时候同时添加主键索引: 一.如何添加主键索引 修改表添加主键索引 Alter tab ...
- 【实施工程师之家】——mysql四种索引PRIMARY(主键索引)、INDEX(一般索引)、UNIQUE(非空索引)、FULLTEXT(全文索引)应用
mysql四种索引PRIMARY(主键索引).INDEX(一般索引).UNIQUE(非空索引).FULLTEXT(全文索引)应用 目录 1)PRIMARY: 2)NORMAL: 3)UNIQUE: 4 ...
- mysql非主键索引_主键索引和非主键索引的区别
1. 什么是最左前缀原则? 以下回答全部是基于MySQL的InnoDB引擎 例如对于下面这一张表 如果我们按照 name 字段来建立索引的话,采用B+树的结构,大概的索引结构如下 如果我们要进行模糊查 ...
- 主键索引 or 辅助索引?一文告诉你 Mysql limit 优化时的索引选择!
作者 | 吴海存 责编 | 徐威龙 封图| CSDN下载于视觉中国 导读: 本文主要针对limit分页时,是优先基于主键索引还是辅助索引等层面展开分析,对limit及offset的用法以及是否该用索引 ...
- mysql索引类型和区别是什么意思_mysql主键索引和普通索引之间的区别是什么
索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.MySQL提供多种索引类型供选择:普通索引 .唯一性索引.主键索引 .全文索引等等.下面本篇文章就来给大家介绍一下主键索 ...
- Mysql 主键 联合主键 索引 唯一索引 被抠细节问死的问题
1.一张表中可以有几个主键? 答:一个. 2.那联合主键是什么? 答:一张表多个主键,就是联合主键,可以由多个列形成联合主键,但是主键只能有一个 3.主键作用是什么? 答:主键的作用是保证数据的唯一性 ...
- mysql主键索引和普通索引之间的区别
索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.MySQL提供多种索引类型供选择:普通索引 .唯一性索引.主键索引 .全文索引等等.下面本篇文章就来给大家介绍一下主键索 ...
- MySQL主键索引和唯一索引区别
MySQL主键索引和唯一索引区别 什么是最左前缀原则? 以下回答全部是基于MySQL的InnoDB引擎 例如对于下面这一张表 如果我们按照 name 字段来建立索引的话,采用B+树的结构,大概的索引结 ...
最新文章
- 基于特征的推荐算法【转】
- 计算字符串的实际长度
- VTK:图片之Transparency
- 基于 FFmpeg 的播放器 demo
- 前端也要懂Http缓存机制
- IE6/IE7/Firefox浏览器不兼容原因及解决办法
- LeetCode 973. 最接近原点的 K 个点(排序/优先队列/快排)
- 【Java】不要直接使用引用未判空的对象
- vue template 复用_vue-组件基础
- 关于Gateway的几个问题
- MySQL索引的使用知识有哪些?
- C-从源文件到可执行文件的详细编译链接过程
- 基于Springboot+MySQL的个人健康监控管理系统
- 怎么批量查询银行卡号发卡行等信息?
- python编程输入名字配对情侣网名_输入名字制作情侣qq网名
- Linux C实现纯用户态抢占式多线程!
- 计算机操作系统-磁盘存储器
- Openlayers:Polygon绘图工具
- 玩转Kaggle:Dog Breed Identification【识别狗的类别】
- 如何放大图片,教您三种方法!