赞
踩
索引,是一种物理概念,是关系数据库中对某一列或多个列的值进行预排序的数据结构。通过使用索引,可以让数据库系统不必扫描全表,快速定位到符合条件的记录,这样就大大加快了查询速度。
索引分类:
PRIMARY KEY(key);
在innodb中,主键索引的B+树包含表数据信息。
UNIQUE(key)
INDEX(key)
-- OR
KEY(key[,...])
INDEX idx(key1,key2[,...]);
UNIQUE(key1,key2[,...]);
PRIMARY KEY(key1,key2[,...]);
约束,是指对表中数据的一种约束,能够帮助数据库管理员更好地管理数据库,并且能够确保数据库中数据的正确性和有效性。
创建主键索引或者唯一索引的时候同时创建了相应的约束;但是约束时逻辑上的概念;索引是一个数据结构既包含逻辑的概念也包含物理的存储方式;
约束分类:
其中MyISAM存储引擎本身并不支持外键,只起到注释作用;而innodb完整支持外键;
innodb由段、区、页组成;段分为数据段、索引段、回滚段;区大小为1MB(一个区由64个连续页组成);页的默认值是16K;页为逻辑页,磁盘物理页大小一般为4K或者8K,为了保证区中的页的连续,存储引擎一般一次从磁盘中申请4-5个区。索引在磁盘中是以B+树的方式存储的。
页是innodb磁盘管理的最小单元,默认16k,可通过innodb_page_size参数来修改。B+树的一个节点的大小就是该页的值。
索引在磁盘中是以B+树的方式存储的。
B+树全称是多路平衡搜索树,,它用来组织磁盘数据,能够减少磁盘访问次数。它以页为单位,对页的访问是一次磁盘io。缓存中会缓存常访问的页。
它的特征是:非叶子节点只存储索引信息,叶子节点存储具体数据信息。叶子节点之间互相连接,方便范围查询。
每个索引都对应着一个B+树。
B+树的一个节点对应一个数据页;B+树的层越高,那么要读取到内存的数据页越多,io次数越多。
自增id超过类型最大值会报错。如果自增id是bigint,假设一秒钟插入1亿条数据,大概需要5849年才会用完索引。
从实现方式上,索引可以分为聚集索引和辅助索引。聚集索引里存储的有全部的行记录,而辅助索引里只有部分的行记录。
innodb两个索引都有,但是MyISAM只有辅助索引。
聚集索引是按照主键构造的B+树,叶子节点中存放数据页。这表明数据也是索引的一部分。其他节点则只存储了primary key,以提供索引功能。聚集索引示意图如下所示:
根据B+树的定义,一个节点至少要存储两行数据,如果某个表一行的数据就大于16K,那么会对行数据进行拆分,B+树的一个节点只会存储一行的6、7K的数据,其他的数据则存储在其他位置,并由指针指向那里。
叶子节点不包含行记录的全部数据,它只包含用来排序的key和bookmark。bookmark存储了聚集索引的key。其他节点也是只存储了key,只提供索引功能。
Innodb的体系结构如下图所示:
Buffer pool是用来缓存表和索引数据的。它采用LRU算法,让Buffer pool只缓存比较热的数据。
LRU(Least Recently Used)是一种最近最少使用的页面置换算法。Buffer Pool的LRU算法和其他的算法有些许的不同。当一页数据从此番中被查询到的时候,会将这个页面插入到Buffer Pool的中间位置,每当Buffer Pool中的页被访问到了,页就会被Buffer Pool中前移一个单位。当Buffer Pool满了之后,会将最后一页的内容移除。
Change buffer缓存非唯一索引的数据变更(DML操作),Change buffer中的数据将会异步merge到磁盘中。
对于组合索引,从左到右依次匹配,遇到范围查询( ><between like)就停止匹配。
从辅助索引中就能找到的数据,就不需要通过聚集索引查找。辅助索引树高度一般低于聚集索引树,所以如果能够使用辅助索引,就使用辅助索引,这样能减少磁盘IO。
mysql优化器主要针对IO和CPU会计算语句的成本,可能不会按照分析的原理来执行语句。
优化器分析成本的步骤是:
SHOW VARIABLES LIKE 'optimizer_trace';
-- 启用优化器的追踪
SET optimizer_trace='enabled=on';
-- 执行一条查询语句
SELECT * FROM information_schema.optimizer_trace;
-- 用完关闭
SET optimizer_trace="enabled=off";
SHOW VARIABLES LIKE 'optimizer_trace';
explain是用来用来查看SQL语句的具体执行过程。
前面添加explain的SQL语句,不会真正执行SQL语句,只是会模拟优化器执行SQL查询语句,从而知道MySQL是如何处理SQL语句的。
分析结果的每个字符段如下表所示:
Column | Meaning |
---|---|
id | The SELECT identifier (查询id) |
select_type | The SELECT type (查询类型 |
table | The table for the output row (输出结果集的表) |
partitions | The matching partitions (匹配的分区) |
type | The join type (表的连接类型) |
possible_keys | The possible indexes to choose(可能使用的索引) |
key | The index actually chosen (实际使用的索引) |
key_len | The length of the chosen key (索引字段的长度) |
ref | The columns compared to the index (列与索引的比较) |
rows | Estimate of rows to be examined (预估扫描行数) |
filtered | Percentage of rows filtered by table condition (按表条件过滤的行百分比) |
extra | Additional information (额外信息,如是否使用索引覆盖) |
MySQL的慢查询日志是用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。long_query_time默认的是10s。
默认情况下,MySQL不会开启慢查询日志,它需要我们手动开启,因为开启它会带来一定的性能影响。如果不是调优需要,不建议启动该参数。
使用慢日志查询的代码如下所示:
-- 查看
SHOW GLOBAL VARIABLES LIKE 'slow_query%';
SHOW GLOBAL VARIABLES LIKE 'long_query%';
-- 设置
SET GLOBAL slow_query_log = ON; -- on 开启 off 关闭
SET GLOBAL long_query_time = 4; -- 单位秒;默认10s;此时设置为4s
-- 或者修改配置
slow_query_log = ON
long_query_time = 4
slow_query_log_file = D:/mysql/mysql57-slow.log
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。