mysql优化-------Myisam与innodb引擎,索引文件的区别

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介:
复制代码
Myisam与innodb引擎,索引文件的区别:
innodb的次索引指向对主键的引用。
myisam的次索引和主索引都指向物理行。

myisam一行一行的插入,会产生一行一行的文件,磁盘上有数据文件。
tree树的值是磁盘上物理位置的指针。

比如加了主键索引,索引排成一棵树的形状。首先根据id=7在主键索引的树上查找,查找到7之后就知道了7所在的物理行,然后就可以找到id=7的那一行数据了。
还有一个cat_id索引,根据cat_id=15可以找到数据所在的物理行。
所以说myisam的次索引和主索引都指向物理行。
复制代码

innodb的主键索引,数的每一个叶子下面,直接挂在了每行的数据,id=5的地方挂载的就是id=5的这行数据。数据就在叶子上,不用去磁盘上面查找。如果还有其他索引username,username=li的叶子下面放的是id=7.根据username索引这棵树上找到id=7然后在主键树上找到数据。
所以innodb的次索引指向对主键的引用。id的主索引成为聚簇索引,好处是根据主键查非常快,坏处是根据其他索引找的时候要多找一次主键这棵树。username是非聚簇索引。

 

复制代码
innodb的主索引文件上 直接存放该行数据,称为聚簇索引,次索引指向对主键的引用。
myisam中, 主索引和次索引,都指向物理行(磁盘位置)。

注意: innodb来说, 
1: 主键索引 既存储索引值,又在叶子中存储行的数据
2: 如果没有主键, 则会Unique key做主键 
3: 如果没有unique,则系统生成一个内部的rowid做主键.
4: 像innodb中,主键的索引结构中,既存储了主键值,又存储了行数据,这种结构称为"聚簇索引"


聚簇索引 
优势: 根据主键查询条目比较少时,不用回行(数据就在主键节点下)
劣势: 如果碰到不规则数据插入时,造成频繁的页分裂.

myisam中对于索引文件是要放在内存中缓存起来的。节点会分裂:原来19的节点后来来了15和13,则19的位置换成13,并在下面添加15,19。对于聚簇索引就很严重。对于myisam没什么,对于innodb就很麻烦。
复制代码

高性能索引策略
对于innodb而言,因为节点下有数据文件,因此节点的分裂将会比较慢.
对于innodb的主键,尽量用整型,而且是递增的整型.
如果是无规律的数据,将会产生的页的分裂,影响速度.

 

复制代码
create table A{
    id varchar(64) primary key,
    ver int,
}
在id和ver上有联合索引10000条数据。
为什么select id from A order by id很慢
而select id from A order by id,ver很快
 
如果用的是myisam,那么都用到了索引覆盖,应该是一样都很快,有可能不实用的myisam引擎。myisam无论使用什么索引都是指向物理行的位置。


如果是innodb引擎,每个叶子下面直接放的数据,这些数据比较大内存放不下,就放在磁盘上。innodb的主键是聚簇索引。有比较长的列,聚簇索引导致沿id排序时要跨好多块。而且块比较多。所以查找很慢。

第二句是联合索引,联合索引没有放数据块(除了主键索引其余索引都指向主键索引,不带数据),而是放的是主键索引的位置指向id的值,不带有数据,文件比较小可以在内存中存放。现在只是取出id不用回行,就是在索引文件中取,而且索引文件比较小就放在内存中,所以很快。第一个语句,也只是在索引文件中查找,发生了索引覆盖,但是这个主键索引文件比较大,而且不一定在内存中,查找主键树的时候来回跳跃就很慢。

如果把数据比较大的字段去掉,速度也会提升,因为查找主键索引文件来回跳的时候就不会慢了。
复制代码

 

 

 

 

通过下面的规律可以看出-----
1: innodb的buffer_page 很强大.
2: 聚簇索引的主键值,应尽量是连续增长的值,而不是要是随机值, (不要用随机字符串或UUID)
否则会造成大量的页分裂与页移动.
复制代码
实验: 聚簇索引使用随机值导致页频繁分裂影响速度
过程:建立innodb表, 利用php连接mysql,
分别规则插入10000条数据,不规则插入10000条数据
观察时间的差异,体会聚簇索引,页分裂的影响.  


create table t5(
id int primary key,
c1 varchar(500),
c2 varchar(500),
c3 varchar(500),
c4 varchar(500),
c5 varchar(500),
c6 varchar(500)
) engine innodb charset utf8;

create table t6(
id int primary key,
c1 varchar(500),
c2 varchar(500),
c3 varchar(500),
c4 varchar(500),
c5 varchar(500),
c6 varchar(500)
) engine innodb charset utf8;



// testinnodb.php
$time_start = microtime_float();

$str = str_repeat('hello',100);
for($i=1;$i<=10000;$i++) {
   $sql = "insert into t5 values ($i,'$str' , '$str' , '$str' , '$str' , '$str' , '$str'
)";
   //echo $sql;
   mysql_query($sql , $conn);
}

$time_end = microtime_float();
echo 'seq insert cost' , ($time_end - $time_start) , "seconds\n";
function microtime_float()
{
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}

// rndinnodb.php
$base = range(1,10000);
shuffle($base);

$time_start = microtime_float();
$str = str_repeat('hello',100);
foreach($base as $i) {
   $sql = "insert into t6 values ($i,'$str' , '$str' , '$str' , '$str' , '$str' , '$str'
)";
   //echo $sql;
   mysql_query($sql , $conn);
}

$time_end = microtime_float();
echo 'rand insert cost' , ($time_end - $time_start) , "seconds\n";

function microtime_float()
{
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}
复制代码

字段数

混乱程度(步长)

顺序1000(秒数)

乱序1000(秒数)

顺序写入page页数

乱序写入page

1

1

54.365

53.438

62

91

10

1

53.413

62.940

235

1301

10

100

 

64.18

 

1329

10

1000

 

67.512

 

1325

 

通过上面的规律可以看出-----
1: innodb的buffer_page 很强大.
2: 聚簇索引的主键值,应尽量是连续增长的值,而不是要是随机值, (不要用随机字符串或UUID)
否则会造成大量的页分裂与页移动.

 


本文转自农夫山泉别墅博客园博客,原文链接:http://www.cnblogs.com/yaowen/p/8268274.html,如需转载请自行联系原作者

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
19天前
|
存储 关系型数据库 MySQL
MySQL细节优化:关闭大小写敏感功能的方法。
通过这种方法,你就可以成功关闭 MySQL 的大小写敏感功能,让你的数据库操作更加便捷。
80 19
|
2月前
|
SQL 关系型数据库 MySQL
基于SQL Server / MySQL进行百万条数据过滤优化方案
对百万级别数据进行高效过滤查询,需要综合使用索引、查询优化、表分区、统计信息和视图等技术手段。通过合理的数据库设计和查询优化,可以显著提升查询性能,确保系统的高效稳定运行。
76 9
|
2月前
|
监控 关系型数据库 MySQL
MySQL和SQLSugar百万条数据查询分页优化
在面对百万条数据的查询时,优化MySQL和SQLSugar的分页性能是非常重要的。通过合理使用索引、调整查询语句、使用缓存以及采用高效的分页策略,可以显著提高查询效率。本文介绍的技巧和方法,可以为开发人员在数据处理和查询优化中提供有效的指导,提升系统的性能和用户体验。掌握这些技巧后,您可以在处理海量数据时更加游刃有余。
205 9
|
2月前
|
关系型数据库 MySQL
图解MySQL【日志】——磁盘 I/O 次数过高时优化的办法
当 MySQL 磁盘 I/O 次数过高时,可通过调整参数优化。控制刷盘时机以降低频率:组提交参数 `binlog_group_commit_sync_delay` 和 `binlog_group_commit_sync_no_delay_count` 调整等待时间和事务数量;`sync_binlog=N` 设置 write 和 fsync 频率,`innodb_flush_log_at_trx_commit=2` 使提交时只写入 Redo Log 文件,由 OS 择机持久化,但两者在 OS 崩溃时有丢失数据风险。
71 3
|
24天前
|
关系型数据库 MySQL Java
【YashanDB知识库】原生mysql驱动配置连接崖山数据库
【YashanDB知识库】原生mysql驱动配置连接崖山数据库
【YashanDB知识库】原生mysql驱动配置连接崖山数据库
|
29天前
|
关系型数据库 MySQL 数据库连接
docker拉取MySQL后数据库连接失败解决方案
通过以上方法,可以解决Docker中拉取MySQL镜像后数据库连接失败的常见问题。关键步骤包括确保容器正确启动、配置正确的环境变量、合理设置网络和权限,以及检查主机防火墙设置等。通过逐步排查,可以快速定位并解决连接问题,确保MySQL服务的正常使用。
245 82
|
3月前
|
关系型数据库 MySQL 数据库连接
数据库连接工具连接mysql提示:“Host ‘172.23.0.1‘ is not allowed to connect to this MySQL server“
docker-compose部署mysql8服务后,连接时提示不允许连接问题解决
|
1月前
|
消息中间件 缓存 NoSQL
缓存与数据库的一致性方案,Redis与Mysql一致性方案,大厂P8的终极方案(图解+秒懂+史上最全)
缓存与数据库的一致性方案,Redis与Mysql一致性方案,大厂P8的终极方案(图解+秒懂+史上最全)
|
2月前
|
关系型数据库 MySQL 数据库
Docker Compose V2 安装常用数据库MySQL+Mongo
以上内容涵盖了使用 Docker Compose 安装和管理 MySQL 和 MongoDB 的详细步骤,希望对您有所帮助。
244 42