mysql更新(八) 可视化工具Navicat的使用 索引

时间:2021-11-07 03:43:47

17-索引

 

一、索引的介绍

数据库中专门用于帮助用户快速查找数据的一种数据结构。类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置吗,然后直接获取。

二 、索引的作用

约束和加速查找

三、常见的几种索引:

mysql更新(八) 可视化工具Navicat的使用 索引
- 普通索引
- 唯一索引
- 主键索引
- 联合索引(多列)

- 联合主键索引

  - 联合唯一索引   
 - 联合普通索引
mysql更新(八) 可视化工具Navicat的使用 索引
mysql更新(八) 可视化工具Navicat的使用 索引mysql更新(八) 可视化工具Navicat的使用 索引
mysql更新(八) 可视化工具Navicat的使用 索引
无索引: 从前往后一条一条查询
有索引:创建索引的本质,就是创建额外的文件(某种格式存储,查询的时候,先去格外的文件找,定好位置,然后再去原始表中直接查询。但是创建索引越多,会对硬盘也是有损耗。

建立索引的目的:
a.额外的文件保存特殊的数据结构
b.查询快,但是插入更新删除依然慢
c.创建索引之后,必须命中索引才能有效
mysql更新(八) 可视化工具Navicat的使用 索引
无索引和有索引的区别以及建立索引的目的
mysql更新(八) 可视化工具Navicat的使用 索引mysql更新(八) 可视化工具Navicat的使用 索引
hash索引和BTree索引
(1)hash类型的索引:查询单条快,范围查询慢
(2)btree类型的索引:b+树,层数越多,数据量指数级增长(我们就用它,因为innodb默认支持它)
索引的种类

 

3.1 普通索引

作用:仅有一个加速查找

mysql更新(八) 可视化工具Navicat的使用 索引mysql更新(八) 可视化工具Navicat的使用 索引
mysql更新(八) 可视化工具Navicat的使用 索引
create table userinfo(
                   nid int not null auto_increment primary key,
                   name varchar(32) not null,
                   email varchar(64) not null,
                   index ix_name(name)
               );
mysql更新(八) 可视化工具Navicat的使用 索引
创建表+普通索引
mysql更新(八) 可视化工具Navicat的使用 索引mysql更新(八) 可视化工具Navicat的使用 索引
create index 索引的名字 on 表名(列名)
普通索引
mysql更新(八) 可视化工具Navicat的使用 索引mysql更新(八) 可视化工具Navicat的使用 索引
drop index 索引的名字 on 表名
删除索引
mysql更新(八) 可视化工具Navicat的使用 索引mysql更新(八) 可视化工具Navicat的使用 索引
show index from 表名
查看索引

3.2 唯一索引

 唯一索引有两个功能:加速查找和唯一约束(可含null)

mysql更新(八) 可视化工具Navicat的使用 索引mysql更新(八) 可视化工具Navicat的使用 索引
mysql更新(八) 可视化工具Navicat的使用 索引
  create table userinfo(
                   id int not null auto_increment primary key,
                   name varchar(32) not null,
                   email varchar(64) not null,
                   unique  index  ix_name(name)
               );
mysql更新(八) 可视化工具Navicat的使用 索引
创建表+唯一索引
mysql更新(八) 可视化工具Navicat的使用 索引mysql更新(八) 可视化工具Navicat的使用 索引
create unique index 索引名 on 表名(列名)
唯一索引
mysql更新(八) 可视化工具Navicat的使用 索引mysql更新(八) 可视化工具Navicat的使用 索引
drop index 索引名 on 表名;
删除唯一索引

 

3.3 主键索引

主键索引有两个功能: 加速查找和唯一约束(不含null)

mysql更新(八) 可视化工具Navicat的使用 索引mysql更新(八) 可视化工具Navicat的使用 索引
mysql更新(八) 可视化工具Navicat的使用 索引
    create table userinfo(

                   id int not null auto_increment primary key,
                   name varchar(32) not null,
                   email varchar(64) not null,
                   unique  index  ix_name(name)
           )
          or

           create table userinfo(

                   id int not null auto_increment,
                   name varchar(32) not null,
                   email varchar(64) not null,
                   primary key(nid),
                   unique  index  ix_name(name)
         )
mysql更新(八) 可视化工具Navicat的使用 索引
创建表+主键索引
mysql更新(八) 可视化工具Navicat的使用 索引mysql更新(八) 可视化工具Navicat的使用 索引
alter table 表名 add primary key(列名);
主键索引
mysql更新(八) 可视化工具Navicat的使用 索引mysql更新(八) 可视化工具Navicat的使用 索引
alter table 表名 drop primary key;
alter table 表名  modify  列名 int, drop primary key;
删除主键索引

3.4 组合索引

 组合索引是将n个列组合成一个索引

 其应用场景为:频繁的同时使用n列来进行查询,如:where name = 'alex' and email = 'alex@qq.com'。

mysql更新(八) 可视化工具Navicat的使用 索引mysql更新(八) 可视化工具Navicat的使用 索引
create index 索引名 on 表名(列名1,列名2);
联合普通索引

四、索引名词

mysql更新(八) 可视化工具Navicat的使用 索引
#覆盖索引:在索引文件中直接获取数据
        例如:
        select name from userinfo where name = 'alex50000';


#索引合并:把多个单列索引合并成使用
        例如:
        select * from  userinfo where name = 'alex13131' and id = 13131;
mysql更新(八) 可视化工具Navicat的使用 索引

六、正确使用索引的情况

  数据库表中添加索引后确实会让查询速度起飞,但前提必须是正确的使用索引来查询,如果以错误的方式使用,则即使建立索引也会不奏效。

  使用索引,我们必须知道:

    (1)创建索引 

    (2)命中索引

    (3)正确使用索引

 准备:

mysql更新(八) 可视化工具Navicat的使用 索引mysql更新(八) 可视化工具Navicat的使用 索引
mysql更新(八) 可视化工具Navicat的使用 索引
#1. 准备表
create table userinfo(
id int,
name varchar(20),
gender char(6),
email varchar(50)
);

#2. 创建存储过程,实现批量插入记录
delimiter $$ #声明存储过程的结束符号为$$
create procedure auto_insert1()
BEGIN
    declare i int default 1;
    while(i<3000000)do
        insert into userinfo values(i,concat('alex',i),'male',concat('egon',i,'@oldboy'));
        set i=i+1;
    end while;
END$$ #$$结束
delimiter ; #重新声明分号为结束符号

#3. 查看存储过程
show create procedure auto_insert1\G 

#4. 调用存储过程
call auto_insert1();
mysql更新(八) 可视化工具Navicat的使用 索引
准备300w条数据

  测试:

mysql更新(八) 可视化工具Navicat的使用 索引
     - like '%xx'
            select * from userinfo where name like '%al';
        - 使用函数
            select * from userinfo where reverse(name) = 'alex333';
        - or
            select * from userinfo where id = 1 or email = 'alex122@oldbody';
            特别的:当or条件中有未建立索引的列才失效,以下会走索引
                    select * from userinfo where id = 1 or name = 'alex1222';
                    select * from userinfo where id = 1 or email = 'alex122@oldbody' and name = 'alex112'
        - 类型不一致
            如果列是字符串类型,传入条件是必须用引号引起来,不然...
            select * from userinfo where name = 999;
        - !=
            select count(*) from userinfo where name != 'alex'
            特别的:如果是主键,则还是会走索引
                select count(*) from userinfo where id != 123
        - >
            select * from userinfo where name > 'alex'
            特别的:如果是主键或索引是整数类型,则还是会走索引
                select * from userinfo where id > 123
                select * from userinfo where num > 123
        - order by
            select email from userinfo order by name desc;
            当根据索引排序时候,选择的映射如果不是索引,则不走索引
            特别的:如果对主键排序,则还是走索引:
                select * from userinfo order by nid desc;
         
        - 组合索引最左前缀
            如果组合索引为:(name,email)
            name and email       -- 使用索引
            name                 -- 使用索引
            email                -- 不使用索引
mysql更新(八) 可视化工具Navicat的使用 索引

什么是最左前缀呢?

mysql更新(八) 可视化工具Navicat的使用 索引
最左前缀匹配:
        create index ix_name_email on userinfo(name,email);
                 select * from userinfo where name = 'alex';
                 select * from userinfo where name = 'alex' and email='alex@oldBody';

                 select * from userinfo where  email='alex@oldBody';

             如果使用组合索引如上,name和email组合索引之后,查询
             (1)name和email ---使用索引
             (2)name        ---使用索引
             (3)email       ---不适用索引
              对于同时搜索n个条件时,组合索引的性能好于多个单列索引
        ******组合索引的性能>索引合并的性能*********
mysql更新(八) 可视化工具Navicat的使用 索引

七、索引的注意事项

mysql更新(八) 可视化工具Navicat的使用 索引
       (1)避免使用select *
       (2)count(1)或count(列) 代替count(*)
       (3)创建表时尽量使用char代替varchar
       (4)表的字段顺序固定长度的字段优先
       (5)组合索引代替多个单列索引(经常使用多个条件查询时)
       (6)尽量使用短索引 (create index ix_title on tb(title(16));特殊的数据类型 text类型)
       (7)使用连接(join)来代替子查询
       (8)连表时注意条件类型需一致
       (9)索引散列(重复少)不适用于建索引,例如:性别不合适
mysql更新(八) 可视化工具Navicat的使用 索引

八、执行计划

  explain + 查询SQL - 用于显示SQL执行信息参数,根据参考信息可以进行SQL优化

  

mysql更新(八) 可视化工具Navicat的使用 索引
mysql> explain select * from userinfo;
    +----+-------------+----------+------+---------------+------+---------+------+---------+-------+
    | id | select_type | table    | type | possible_keys | key  | key_len | ref  | rows    | Extra |
    +----+-------------+----------+------+---------------+------+---------+------+---------+-------+
    |  1 | SIMPLE      | userinfo | ALL  | NULL          | NULL | NULL    | NULL | 2973016 | NULL  |
    +----+-------------+----------+------+---------------+------+---------+------+---------+-------+

    mysql> explain select * from (select id,name from userinfo where id <20) as A;
    +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
    | id | select_type | table      | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
    +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
    |  1 | PRIMARY     | <derived2> | ALL   | NULL          | NULL    | NULL    | NULL |   19 | NULL        |
    |  2 | DERIVED     | userinfo   | range | PRIMARY       | PRIMARY | 4       | NULL |   19 | Using where |
    +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
    2 rows in set (0.05 sec)
mysql更新(八) 可视化工具Navicat的使用 索引

参数说明:

mysql更新(八) 可视化工具Navicat的使用 索引
select_type:
                查询类型
                    SIMPLE          简单查询
                    PRIMARY         最外层查询
                    SUBQUERY        映射为子查询
                    DERIVED         子查询
                    UNION           联合
                    UNION RESULT    使用联合的结果
table:
                正在访问的表名
type:
                查询时的访问方式,性能:all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const
                ALL             全表扫描,对于数据表从头到尾找一遍
                                select * from userinfo;
                                特别的:如果有limit限制,则找到之后就不在继续向下扫描
                                       select * from userinfo where email = 'alex112@oldboy'
                                       select * from userinfo where email = 'alex112@oldboy' limit 1;
                                       虽然上述两个语句都会进行全表扫描,第二句使用了limit,则找到一个后就不再继续扫描。

INDEX :      全索引扫描,对索引从头到尾找一遍
                                select nid from userinfo;

RANGE:        对索引列进行范围查找
                                select *  from userinfo where name < 'alex';
                                PS:
                                    between and
                                    in
                                    >   >=  <   <=  操作
                                    注意:!= 和 > 符号


INDEX_MERGE:  合并索引,使用多个单列索引搜索
                                select *  from userinfo where name = 'alex' or nid in (11,22,33);

REF:       根据索引查找一个或多个值
                                select *  from userinfo where name = 'alex112';

EQ_REF:    连接时使用primary key 或 unique类型
                                select userinfo2.id,userinfo.name from userinfo2 left join tuserinfo on userinfo2.id = userinfo.id;



CONST:常量
            表最多有一个匹配行,因为仅有一行,在这行的列值可被优化器剩余部分认为是常数,const表很快,因为它们只读取一次。
                 select id from userinfo where id = 2 ;

SYSTEM:系统
             表仅有一行(=系统表)。这是const联接类型的一个特例。
                 select * from (select id from userinfo where id = 1) as A;


possible_keys:可能使用的索引
key:真实使用的 key_len:  MySQL中使用索引字节长度 rows: mysql估计为了找到所需的行而要读取的行数 ------ 只是预估值 extra: 该列包含MySQL解决查询的详细信息 “Using index” 此值表示mysql将使用覆盖索引,以避免访问表。不要把覆盖索引和index访问类型弄混了。 “Using where” 这意味着mysql服务器将在存储引擎检索行后再进行过滤,许多where条件里涉及索引中的列,当(并且如果)它读取索引时,就能被存储引擎检验,因此不是所有带where子句的查询都会显示“Using where”。有时“Using where”的出现就是一个暗示:查询可受益于不同的索引。 “Using temporary” 这意味着mysql在对查询结果排序时会使用一个临时表。 “Using filesort” 这意味着mysql会对结果使用一个外部索引排序,而不是按索引次序从表里读取行。mysql有两种文件排序算法,这两种排序方式都可以在内存或者磁盘上完成,explain不会告诉你mysql将使用哪一种文件排序,也不会告诉你排序会在内存里还是磁盘上完成。 “Range checked for each record(index map: N)” 这个意味着没有好用的索引,新的索引将在联接的每一行上重新估算,N是显示在possible_keys列中索引的位图,并且是冗余的
mysql更新(八) 可视化工具Navicat的使用 索引

九、慢日志记录

开启慢查询日志,可以让MySQL记录下查询超过指定时间的语句,通过定位分析性能的瓶颈,才能更好的优化数据库系统的性能。

mysql更新(八) 可视化工具Navicat的使用 索引
(1) 进入MySql 查询是否开了慢查询
         show variables like 'slow_query%';
         参数解释:
             slow_query_log 慢查询开启状态  OFF 未开启 ON 为开启
        slow_query_log_file 慢查询日志存放的位置(这个目录需要MySQL的运行帐号的可写权限,一般设置为MySQL的数据存放目录)

(2)查看慢查询超时时间 show variables like 'long%'; ong_query_time 查询超过多少秒才记录 默认10秒 (3)开启慢日志(1)(是否开启慢查询日志,1表示开启,0表示关闭。) set global slow_query_log=1; (4)再次查看 show variables like '%slow_query_log%'; (5)开启慢日志(2):(推荐) 在my.cnf 文件中 找到[mysqld]下面添加: slow_query_log =1      slow_query_log_file=C:\mysql-5.6.40-winx64\data\localhost-slow.log     long_query_time = 1 参数说明: slow_query_log 慢查询开启状态 1 为开启 slow_query_log_file 慢查询日志存放的位置 long_query_time 查询超过多少秒才记录 默认10秒 修改为1秒
mysql更新(八) 可视化工具Navicat的使用 索引

 

十、分页性能相关方案

先回顾一下,如何取当前表中的前10条记录,每十条取一次.......

mysql更新(八) 可视化工具Navicat的使用 索引
第1页:
select * from userinfo limit 0,10;
第2页:
select * from userinfo limit 10,10;
第3页:
select * from userinfo limit 20,10;
第4页:
select * from userinfo limit 30,10;
......
第2000010页
select * from userinfo limit 2000000,10;

PS:会发现,越往后查询,需要的时间约长,是因为越往后查,全文扫描查询,会去数据表中扫描查询。
mysql更新(八) 可视化工具Navicat的使用 索引

最优的解决方案

mysql更新(八) 可视化工具Navicat的使用 索引
(1)只有上一页和下一页
        做一个记录:记录当前页的最大id或最小id
        下一页:
        select * from userinfo where id>max_id limit 10;

        上一页:
        select * from userinfo where id<min_id order by id desc limit 10;


  (2) 中间有页码的情况
           select * from userinfo where id in(
               select id from (select * from userinfo where id > pre_max_id limit (cur_max_id-pre_max_id)*10) as A order by A.id desc limit 10
           );    
mysql更新(八) 可视化工具Navicat的使用 索引
 
 

15-可视化工具Navicat的使用

 

本节重点:

  • 掌握Navicat的基本使用

 

 

# PS:在生产环境中操作MySQL数据库还是推荐使用命令行工具mysql,但在我们自己开发测试时,可以使用可视化工具Navicat,以图形界面的形式操作MySQL数据库

 

 

官网下载:https://www.navicat.com/en/products/navicat-for-mysql

网盘下载:https://pan.baidu.com/s/1bpo5mqj

 

需要掌握基本的操作

mysql更新(八) 可视化工具Navicat的使用 索引
掌握:
#1. 测试+链接数据库
#2. 新建库
#3. 新建表,新增字段+类型+约束
#4. 设计表:外键
#5. 新建查询
#6. 备份库/表

#注意:
批量加注释:ctrl+?键
批量去注释:ctrl+shift+?键
mysql更新(八) 可视化工具Navicat的使用 索引