innodb 索引问题

  1. extra 值的区别:

一共有如下值mysql

  • Using index
  • using whre using index
  • null
  • using where
  • using index condition
  • using file sort

如今来一一验证如下值的区别以及产生这些值的条件sql

建立表数据库

create table test_order
(
    id int auto_increment primary key,
    user_id int,
    order_id int,
    order_status tinyint,
    create_date datetime
);

create table test_orderdetail
(
    id int auto_increment primary key,
    order_id int,
    product_name varchar(100),
    cnt int,
    create_date datetime
);

create index idx_userid_order_id_createdate on test_order(user_id,order_id,create_date);

create index idx_orderid_productname on test_orderdetail(order_id,product_name);
复制代码

而后执行存储过程 分别生成2张表各 50w条记录缓存

CREATE PROCEDURE `test_insertdata`(IN `loopcount` INT)
    LANGUAGE SQL
    NOT DETERMINISTIC
    CONTAINS SQL
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN
    declare v_uuid  varchar(50);
    while loopcount>0 do
        set v_uuid = uuid();
        insert into test_order (user_id,order_id,order_status,create_date) values (rand()*1000,id,rand()*10,DATE_ADD(NOW(), INTERVAL - RAND()*20000 HOUR));
        insert into test_orderdetail(order_id,product_name,cnt,create_date) values (rand()*100000,v_uuid,rand()*10,DATE_ADD(NOW(), INTERVAL - RAND()*20000 HOUR));
        set loopcount = loopcount -1;
    end while;
END
复制代码

执行函数 使用bash

call test_insertdata(500000);
//或者mysql 客户端点击 运行函数 输入50w 便可
复制代码

Using index

  • 说明:查询的列被索引覆盖,而且where条件 是 ==索引的是前导列==, 则 extra 为 Using index
explain select user_id,order_id,create_date from test_order
where user_id = 1;
复制代码

因此触发Using index 必须知足2个条件markdown

==1. 查询列被索引覆盖,==函数

==2. where条件 是 索引前导列(最左原则)==oop

Using where; Using index

  • 查询的列被索引覆盖,但不是前导列,则extra 为Using where; Using index
explain select user_id,order_id,create_date from test_order where order_id = 1;
复制代码
  • 查询的列被索引覆盖,可是where 筛选条件是前导列的一个范围,一样意味着没法直接经过索引查找查询结果到符合的数据
explain select user_id,order_id,create_date from test_order where order_id >1 and order_id < 5;
复制代码

Null

  • 使用主键索引,则key 为primary, extra 为null
explain select user_id from test_order where id =1;
复制代码
  • 查询的列未被索引覆盖,可是where条件筛选是索引前导列,意味着用到了索引,可是部分字段未被索引覆盖,则须要经过回表的方式来实现
explain select user_id,order_id,order_status,create_date from test_order where user_id =1;
复制代码

Using where

  • 查询的列未被覆盖,where条件不是索引的前导列
explain select user_id,order_id,order_status,create_date from test_order where order_id =1;
复制代码
  • 查询的列未被覆盖,where条件不是索引
explain select user_id,order_id,order_status,create_date from test_order where order_status =1;
复制代码

using where 说明是经过索引或者表扫描的方式进行where 条件的过滤。反过来讲,没有可用的索引查找,因此也须要考虑索引加回表 与 全表扫描之间的代价,若是type 为all 则是全表扫描的意思ui

Using index condition

  1. 查询的不全是 索引,搜索条件是前导列的 (范围 <> 或者 like %)
explain select user_id,order_id,order_status,create_date from test_order where user_id >1 and user_id < 5;
复制代码

索引2大类 汇集索引以及 普通索引atom

  1. 汇集索引一般是 主键索引
B+数结构如图


    1-9
    <>
  1-5 7-9
  <>   <>
 1  5   7   9
 
 1  5   7   9
 A  D   G   J
 B  E   H   K
 C  F   I   L
 
复制代码

如上所示 汇集索引最终指向的是行记录数据

咱们来看一下 普通索引

B+数结构如图

     a - z
      <>
    A-F   G-L
    
    A  F  G  L
    1  5  7  9
复制代码

如上所示 是指向该记录的索引 因此若是想要查询这个记录 咱们须要==回表==的方式进行再一次查询汇集索引

mysql 事务的实现

A atomicity 原子性 概述:将一个事务视为最小单位 要么所有成功,要么总体失败 实现:当事务发生异常的时候,就须要回滚操做,而使用 undo log 来记录 以前操做的语句 -- 若是一旦发生异常,将会执行undo log 里面的语句, 这里要注意的是 undo log 记录的是 反向操做语句 好比insert 对应的是 delete

事务的状态 begin commit failed C Consistency 一致性 一致性的2个理解

  1. 同一个sql,相同的数据库实例,则改变的行记录是一致的
  2. 银行存取钱操做, 这个就须要代码中实现 实现

I Isolation 隔离性 概念:在mysql 并行执行事务的时候,保证可以有序的进行事务执行,则事务须要具有隔离性 实现 锁 悲观锁,乐观锁 杭锁 表锁 行锁 共享锁 互斥锁 4中隔离级别以及衍生处的 幻读,不可重复读 脏读

D Durability 持久性 概念:当一个事务提交后,还没来的急写进磁盘就宕机,则再下一次数据库重启时可以恢复数据,这就是持久性 实现:经过 redo log 重作日志来实现

mysql 执行事务的过程,将行记录从磁盘写到内存中,更新内存中的数据,生成一条重作日志 将修改后的数据写入 redo buffer ,当事务执行时,进而将其写入重作日志中,并将缓存中的数据更新到磁盘中。由于重作日志是512字节 与磁盘扇区大小相同,就能够保证原子性,不会由于断电而写入一半的这种状况。因此当重启后,mysql会从重作日志中从新执行mysql命令,这就是持久性

相关文章
相关标签/搜索