首页 > 数据库 >MYSQL学习笔记之索引

MYSQL学习笔记之索引

时间:2022-10-05 11:05:38浏览次数:43  
标签:index 笔记 索引 emp MYSQL NULL where select

MYSQL学习笔记之索引_索引

(一)什么是索引??

       索引(Index)是在数据库的字段上添加的,是为了提高查询的效率存在的一种机制。一张表的一个字段可以添加一个索引,当然,多个字段联合起来也可以添加索引。索引相当于是一本书的目录,主要是为缩小扫描范围而存在的一种机制。

(二)查询的分类

① 全表扫描(缺点:效率比较低,查询速度比较慢)

② 索引定位(优点:查询速度比较快,效率比较高)​

说明:对于通过索引的这一种查询方式,索引也是需要排序的,并且索引的排序和TreeSet数据结构相同。TreeSet(TreeMap)底层是一个自平衡二叉树!在mysql中索引是一个B-Tree的数据结构。

(三)索引的实现原理

假设存在一张用户表 t_user

    id(PK)                  name            每一行记录在硬盘上都有物理存储编号

------------------------------------------------------------------------------------

     100                      张三                        0x1111

     120                      李四                        0x2222

      99                       王五                        0x8888

      88                       赵六                        0x9999

     101                      小胡                        0x6666

      55                       小明                        0x5555

     130                      小红                        0x7777

说明:

I.在任何数据库当中主键上会自动添加索引对象,id字段上有自动索引。一个字段上如果有unique约束的话,也会自动创建索引对象。

II.在任何数据库当中,任何一张表的任何一条记录都在硬盘上存储都有一个硬盘上的物理编号。

III.在mysql中,所以是一个单独的对象,不同的存储引擎以不同的形式存在,在MYSQL存储引擎中,索引存储在一个.MYI文件中。在InnoDB存储引擎中,索引存储在一个逻辑名称叫做tablespace当中。在MEMORY存储引擎中索引被存储在内存当中。不管索引存储在哪里,索引在mysql中都是一个树的形式存在(自平衡二叉树:B-Tree)

构建与查找图示如下:

MYSQL学习笔记之索引_索引_02

(四)应用场景

① 数据量庞大

② 该字段经常出现在where的后面

③ 该字段进行很少的DML(insert 、delete、update)操作。

(频繁的DML操作会导致索引重新排序,降低效率)

注意:索引是不可以进行随意添加的,索引是需要维护的,索引太多反而会影响系统的性能,通过主键查询或通过unique约束的字段进行查询,效率很高。

(五)如何使用

I.索引的创建

mysql> create index emp_ename_index on emp(ename);
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0

II.索引的删除

mysql> drop index emp_ename_index on emp;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0

III.查看索引方式

mysql> explain select * from emp where ename = 'KING';
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | emp | NULL | ALL | NULL | NULL | NULL | NULL | 14 | 10.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

mysql> create index emp_ename_index on emp(ename);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> explain select * from emp where ename = 'KING';
+----+-------------+-------+------------+------+-----------------+-----------------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+-----------------+-----------------+---------+-------+------+----------+-------+
| 1 | SIMPLE | emp | NULL | ref | emp_ename_index | emp_ename_index | 33 | const | 1 | 100.00 | NULL |
+----+-------------+-------+------------+------+-----------------+-----------------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

说明:MYSQL索引底层是B-Tree

IV.索引失效

情况一:explain select * from emp where ename like '%T';

mysql> explain select * from emp where ename like '%T';
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | emp | NULL | ALL | NULL | NULL | NULL | NULL | 14 | 11.11 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

失效原因:模糊匹配当中条件使用了“%”开头(应该尽量避免)

情况二:explain select  * from emp where ename = 'KING' or job='MANAGER';


mysql> explain select * from emp where ename = 'KING' or job='MANAGER';
+----+-------------+-------+------------+------+-----------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+-----------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | emp | NULL | ALL | emp_ename_index | NULL | NULL | NULL | 14 | 19.00 | Using where |
+----+-------------+-------+------------+------+-----------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

失效原因:在使用or时候,要求其两边的条件字段都需要有索引,才会通过索引进行检索,反之不可以。

#通过使用union来实现
mysql> explain select * from emp where ename = 'KING' union select * from emp where job='MANAGER';
+----+--------------+------------+------------+------+-----------------+-----------------+---------+-------+------+----------+-----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+--------------+------------+------------+------+-----------------+-----------------+---------+-------+------+----------+-----------------+
| 1 | PRIMARY | emp | NULL | ref | emp_ename_index | emp_ename_index | 33 | const | 1 | 100.00 | NULL |
| 2 | UNION | emp | NULL | ALL | NULL | NULL | NULL | NULL | 14 | 10.00 | Using where |
| NULL | UNION RESULT | <union1,2> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary |
+----+--------------+------------+------------+------+-----------------+-----------------+---------+-------+------+----------+-----------------+
3 rows in set, 1 warning (0.00 sec)

情况三:create index emp_job_sal_index on emp(job,sal);

#创建索引
mysql> create index emp_job_sal_index on emp(job,sal);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0

#查看索引次数
mysql> explain select * from emp where job='MANAGER';
+----+-------------+-------+------------+------+-------------------+-------------------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+-------------------+-------------------+---------+-------+------+----------+-------+
| 1 | SIMPLE | emp | NULL | ref | emp_job_sal_index | emp_job_sal_index | 30 | const | 3 | 100.00 | NULL |
+----+-------------+-------+------------+------+-------------------+-------------------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

#查看索引次数
mysql> explain select * from emp where sal = 800;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | emp | NULL | ALL | NULL | NULL | NULL | NULL | 14 | 10.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

失效原因:在复合索引(两个及以上字段联合起来添加索引)中。没有使用左侧的列查找,索引失效。

情况四:explain select * from emp where sal+1=800;

mysql> create index emp_sal_index on emp(sal);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> explain select * from emp where sal=800;
+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+-------+
| 1 | SIMPLE | emp | NULL | ref | emp_sal_index | emp_sal_index | 9 | const | 1 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

mysql> explain select * from emp where sal+1=800;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | emp | NULL | ALL | NULL | NULL | NULL | NULL | 14 | 100.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

失效原因:在where中索引参与了运算。

情况五:explain select * from emp where lower(ename)='smith';

mysql> explain select * from emp where lower(ename)='smith';
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | emp | NULL | ALL | NULL | NULL | NULL | NULL | 14 | 100.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

失效原因: 在where中索引使用了函数

V.索引分类

① 单一索引:一个字段上添加索引。

②复合索引: 两个及以上字段上添加索引。

③主键索引​:主键上添加索引。

④唯一性索引:具有unique约束的字段上添加索引。

标签:index,笔记,索引,emp,MYSQL,NULL,where,select
From: https://blog.51cto.com/u_15314328/5732378

相关文章

  • mongo操作工具类(索引创建等)
    importcn.hutool.core.date.DateUtil;importcom.alibaba.fastjson.JSON;importcom.ft.monitoring.management.OnlineApplication;importcom.mongodb.BasicDBObject......
  • 图论专题-学习笔记:树上启发式合并(dsu on tree)
    目录1.前言2.详解3.总结1.前言树上启发式合并(dsuontree),是一种类似于启发式合并的方式解决关于部分子树内问题的算法,一般都是什么子树内颜色个数等等的。前置知识:......
  • hadoop学习笔记
    XIhadoop​文本文件(索引);​structureddata,RDBMS(表,字段,数据类型,约束);​semi-structureddata,半结构化数据(xml,json);​google(网络爬虫、网络蜘蛛、网络机器人,20亿个页面,unstruc......
  • 新概念第一册41~50单元学习笔记
    Chapterforty-one:Penny'sbagDialogueIsthatbagheavy,Penny?Notvery#口语回答常把主谓宾省略,只剩下一个副词、一个副词词组或一个动词不定式短语等,这里省略主语Itis......
  • 详解线性回归-最小二乘法及其几何意义&最小二乘法-概率视角-高斯噪声-MLE【白板推导系
    $$\begin{gathered}D=\left{(x_{1},y_{1}),(x_{2},y_{2}),\cdots,(x_{N},y_{N})\right}\x_{i}\in\mathbb{R}^{p},y_{i}\in\mathbb{R},i=1,2,\cdots,N\X=\begin{pmat......
  • MySQL/MariaDB如何创建用户并限制指定才能IP访问?
    MySQL/MariaDB如何创建用户并限制指定才能IP访问?登入数据$mysql--versionmysqlVer15.1Distrib10.9.3-MariaDB,fordebian-linux-gnu(x86_64)usingreadline......
  • mysql常用命令
    MySQL常用命令退出mysql:exit查看mysql中有哪些数据库:showdatabases;注意:以分号结尾,分号是英文的分号mysql>showdatabases;+--------------------+|Database......
  • 李超线段树 学习笔记
    Idea主要用于动态维护一个线段或直线集合,支持在平面直角坐标系中插入一条线段或者直线,以及查询某一横坐标上的最值。考虑在x轴上建立一棵线段树,每一个节点\([l,r]\)......
  • 键盘记录器编写笔记
    目录键盘Hook目的实现头文件全局变量DllMain函数Install函数Remove函数KeyboardProc函数DLL调试遇到的问题WindowsAPI例程键盘Hook目的利用Windows钩子监控键盘事件,记......
  • MySQL注入的几种绕过方式
        在平时进行MySQL注入的过程当中,有时会遇到过滤关键字的情况,这篇文章就介绍绕过几种过滤关键字的方式。    绕过过滤and和or    打开sqli的......