作为一个程序猿,平时经常使用数据库,虽然说可以熟练使用数据库,但是对数据库的一些内部原理调优了解不太全面。本文以MySQL为例子,学习数据库的简单原理和一些调优。
在此特别感谢黑马MySQL学习视频。
#查看存储引擎
show engines;
#创建sql指定存储引擎
create table xxx (...) engine=innodb;
innoDB是一种兼顾高可靠性和高性能的通用存储引擎,在MySQL5.5之后,innoDB是默认存储引擎。
特点:
文件:
xxx.ibd:xxx代表的是表名,innoDB引擎的每张表都会对应这样一个表空间文件,存储该表的表结构(frm、sdi)、数据和索引。
参数:innodb_file_per_table;
MyISAM是mysql早期的默认存储引擎。
特点:
文件:
xxx.sdi:存储表结构信息;
xxx.MYD:存储数据;
xxx.MYI:存储索引;
Memory引擎的表数据是存储在内存中的,由于受到硬件问题或者断电问题的影响,只能将这些表作为临时表或缓存使用。
特点:
文件:
xxx.sdi:存储表结构信息;
在选择存储引擎的时候,应该根据应用系统的特点选择合适的存储引擎。对于复杂的应用系统,还可以根据实际情况选择多种存储引擎进行组合。
MySQL索引数据结构对经典的B+Tree进行了优化。在原B+Tree的基础上,增加一个指向相邻叶子节点的链表指针,就形成了带有顺序指针的B+Tree,提高区间访问的性能。
哈希索引就是采用一定的hash算法,将键值换算成新的hash值,映射到对应的槽位上,然后存储在hash表中。
如果两个(或多个)键值,映射到一个相同的槽位上,他们就产生了hash冲突(也称hash碰撞),可以通过链表来解决。
特点:
分类 | 含义 | 特点 | 关键字 |
---|---|---|---|
主键索引 | 针对于表中主键创建的索引 | 默认自动创建,只能有一个 | PRIMARY |
唯一索引 | 避免同一个表中某数据列中的值重复 | 可以有多个 | UNIQUE |
常规索引 | 快速定位特定数据 | 可以有多个 | |
全文索引 | 全文索引查找的是文本中的关键词,而不是比较索引中的值 | 可以有多个 | FULLTEXT |
在innoDB存储引擎中,根据索引的存储形式,又可以分为以下两种:
分类 | 含义 | 特点 |
---|---|---|
聚集索引(clustered index) | 将数据存储与索引放到一块,索引结构的叶子节点保存了行数据 | 必须有,而且自有一个 |
二级索引(secondary index) | 将数据与索引分开存储,索引结构的叶子节点关联的是对应的主键 | 可以存多个 |
聚集索引选取规则:
创建索引:
create [unique|fulltext] index index_name on table_name
查看索引:
show index from table_name
删除索引:
drop index index_name on table_name
show global status like 'Com_________'
优点 | 缺点 |
---|---|
提高数据检索的效率,降低数据库的IO成本 | 索引列也要占用空间 |
通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗 | 索引大大提高查询效率,同时也降低增删改的效率 |
慢查询日志记录了所有执行时间超过指定参数(long_query_time,单位:秒,默认10秒)的所有SQL语句的日志。MySQL的慢查日志默认是没有开启的,需要在MySQL的配置文件(/etc/my.cnf)中配置如下信息:
#开启MySQL慢查日志查询开关
slow_query_log=1
#设置慢日志的时间为2秒,SQL语句执行时间超过2秒,就会视为慢查询,记录慢查询日志
long_query_time=2
配置完毕后,通过以下指令重启MySQL服务器进行测试,查看慢日志文件中的记录的信息 /var/lib/mysql/localhost-slow.log。
查看慢查询是否打开。
show variables like 'slow_query_log';
show profiles 能够在做SQL优化时帮助我们了解时间都消耗到哪里去了。通过have_profiling参数,能够看到当前MySQL是否支持profiles操作。
select @@have_profiling;
默认profiling是关闭的,可以通过set语句在session/global级别开启profiling:
set profiling = 1;
explain或者desc命令获取MySQL如何执行select语句的信息,包括在select语句执行过程中表如何连接和连接顺序。语法:
#直接在select语句之前加上关键字explain或者desc
explain SELECT cloumns_list FROM table_name WHERE query_condition
insert into table_name values(1, 'a'),(2, 'b'),(3, 'c');
start transaction;
insert into table_name values (1, 'a'),(2, 'b),(3,'c');
insert into table_name values (4, 'a'),(5, 'b),(6,'c');
commit;
主键顺序插入
将主键按照顺序插入。
大批量插入数据
如果一次性需要插入大批量数据,使用insert语句插入性能较低,此时可以使用MySQL数据库提供的load指令进行插入。
数据组织方式
在innoDB存储引擎中,表数据都是根据主键顺序组织存放的,这种存储方式的表成为索引组织表(iot)
Using filesort:通过表的索引或全表扫描,读取满足条件的数据行,然后再排序缓冲区中完成排序操作,所有不是通过索引直接返回排序结果的排序都叫filesort排序;
Using index:通过有序索引顺序扫描直接返回有序数据,这种情况即是using index,不需要额外排序,操作效率高;
MyISAM引擎把一个表的总行数存在了磁盘上,因此执行count()的时候会直接返回这个数,效率高;
InnoDB引擎就麻烦了,它执行count()的时候,需要把数据一行一行的从引擎里面读出来,然后累计计数;
MySQL学习