索引和查询优化
 
为什么要索引?
想想我们上小学的时候是怎么查字典的,比方查 理想的 “理”,首先在索引里找到声母 “l”,再找到 “li”
找到 “li”所在的页数,
 
我们之前建的所有mysql 表都是没有索引的,找数据就要全表扫描,想象如果字典里的字都是乱序的,我们
要找一个字的话可能需要翻遍整个字典,
 
同样在msyql 中也有索引,mysql 中的索引有四种:主键,唯一索引,全文索引,普通索引
 
主键
 
主键是不可重复,且不能包含null 的索引
创建主键的方式:
法儿一:
create table pk_test(id int,primary key(id));
法儿二:
alter table test add primary key(f1);
 
主键不可重复指的是主键的组合不重复即可,组成主键的单个字段可能是重复的,例如
MariaDB [jason]> show create table pk_test;
+---------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table   | Create Table                                                                                                                                                               |
+---------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| pk_test | CREATE TABLE `pk_test` (
  `f1` int(11) NOT NULL,
  `f2` int(11) NOT NULL,
  `f3` char(10) DEFAULT NULL,
  PRIMARY KEY (`f1`,`f2`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |
+---------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
 
MariaDB [jason]> insert into pk_test (f1,f2) values(1,1),(1,2);
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0
 
MariaDB [jason]> select * from pk_test;
+----+----+------+
| f1 | f2 | f3   |
+----+----+------+
|  1 |  1 | NULL |
|  1 |  2 | NULL |
+----+----+------+
2 rows in set (0.00 sec)
 
 
普通索引
 
普通索引是可以重复的
创建方式如下:
法儿一:
create table index_test(id int,name char(5),index(name));
法儿二:
alter table index_test add index(id);
 
我们来看下建表语句
MariaDB [jason]> show create table index_test \G;
*************************** 1. row ***************************
       Table: index_test
Create Table: CREATE TABLE `index_test` (
  `id` int(11) DEFAULT NULL,
  `name` char(5) DEFAULT NULL,
  KEY `name` (`name`),
  KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
1 row in set (0.01 sec)
 
怎么就冒出来个 “KEY”,KEY 就是我们刚才建的index ,key 和index 是同义词,不过我一般习惯用index
 
全文索引
 
全文索引是对表中的大文本进行索引的,包括 char,varchar,text,关于全文索引的一些介绍可以看
 
创建全文索引的方法如下
法儿一:
MariaDB [jason]> create table ft_test(f1 char(200),f2 varchar(200),f3 text,f4 int,fulltext(f1));
法儿二:
alter table ft_test add fulltext(f2,f3);
 
现在我们往表里插入两条数据玩玩儿
insert into ft_test(f1,f2,f3) values
('Brian and his two friends are hanging','out at a bar','They are talking about life'),
('sports and other','guy things when the conversation','finally gets around to to their marriages'),
('His first friend says','You know what','under the bed and it was not mine');
 
看看fulltext 的使用方法
 
MariaDB [jason]> select f1 from ft_test where match(f1) against('two');
+---------------------------------------+
| f1                                    |
+---------------------------------------+
| Brian and his two friends are hanging |
+---------------------------------------+
 
我们来看看match against 是个啥玩意儿
MariaDB [jason]> select f1 ,match(f1) against('two') as aa from ft_test;
+---------------------------------------+---------------------+
| f1                                    | aa                  |
+---------------------------------------+---------------------+
| Brian and his two friends are hanging | 0.22764469683170319 |
| sports and other                      |                   0 |
| His first friend says                 |                   0 |
+---------------------------------------+---------------------+
他是一个关联系数,where 条件只过滤系数大于0的记录
 
 噪声单词
 
尝试下面的语句
 
MariaDB [jason]> select f1 from ft_test where match(f1) against('are');
Empty set (0.00 sec)
有什么异样?are 明明在f1 中是存在的,但是结果却是empty,innodb 维持了一个stopword 表,stopword
默认是不被索引的,所以用are 做索引会被忽略
 
唯一索引
 
唯一索引与普通索引类似,区别是唯一索引不可以重复
创建唯一索引的方法
法儿一:
create table uq_test(f1 char(20),f2 char(20),f3 int,unique(f1));
法儿二:
alter table uq_test add unique(f2);
 
 
部分索引
 
对于char,varchar,blob,text 等字符串类型的值,其存储的内容可能很长,如果对整个字段做索引
则索引回很大,且效率很低,这时可以采用部分索引,也叫前缀索引,看例子
 
建表
create table part_index(city char(10));
插入数据
insert into part_index values('hebei'),('beijing'),('tianjin'),('henan'),('anhui');
 
到底选择前缀的几个字符效果最佳呢?可以采用下面的方法计算
MariaDB [jason]> select count(distinct(left(city,1)))/count(*) as c1,
    -> count(distinct(left(city,2)))/count(*) as c2,
    -> count(distinct(left(city,3)))/count(*) as c3,
    -> count(distinct(left(city,4)))/count(*) as c4,
    -> count(distinct(left(city,5)))/count(*) as c5,
    -> count(distinct(city))/count(*) as c6
    -> from part_index;
+--------+--------+--------+--------+--------+--------+
| c1     | c2     | c3     | c4     | c5     | c6     |
+--------+--------+--------+--------+--------+--------+
| 0.8000 | 0.8000 | 1.0000 | 1.0000 | 1.0000 | 1.0000 |
+--------+--------+--------+--------+--------+--------+
 
 
可以看到当选用前3个字符的时候就和使用全部字符比例相当了,所以可以选用前3个字符做前缀索引。
 
那么我们来给上面的表添加前缀索引 
alter table part_index add index(city(3))
 
 
 
 
 
 

《一起学mysql》3的更多相关文章

  1. 百度实习生,以修仙者的角度聊聊怎么学MySQL,不来看看你的修为如何吗?

    目录 因为我个人比较喜欢看修仙类的小说,所以本文的主体部分借用修仙者的修为等级,将学习旅程划分成:练气.筑基.结丹.元婴.化神.飞升六个段位,你可以看下你大概在哪个段位上哦! 本文目录: 我为什么要写 ...

  2. 自导自演的面试现场,趣学MySQL的10种文件

    导读 Hi,大家好!我是白日梦!本文是MySQL专题的第 24 篇. 今天我要跟你分享的MySQL话题是:"自导自演的数据库面试现场--谈谈MySQL的10种文件" 换一种写作风格 ...

  3. DF学Mysql(二)——数据表的基本操作

    1.创建数据表 先使用“USE <数据库名>”指定在哪个数据库中操作 CREATE TABLE <表名> ( 字段1 数据类型 [列级别约束条件] [默认值], 字段2 数据类 ...

  4. 从零开始学MySQL(二)

    鉴于上节篇幅以安装为主,因此对于调用mysql所需要使用的“命令”只是略微提及.随之而来就会带给读者诸多不解了,因为你会思考,这串长长的字符到底有什么特殊的含义呢?聪明的你可能早就抱着好奇心去“摆渡” ...

  5. 从零开始学MySQL(四)

    上节连接:https://www.cnblogs.com/RajXie/p/10880809.html 上节说到,在创建表的同时,需要给出列的定义.列的定义可展开如下: 列名 列的数据类型 列的一些其 ...

  6. Java必学MySQL数据库应用场景

    Java教程分享Java必学之MySQL数据库应用场景,在当前的后台开发中,MySQL应用非常普遍,企业在选拔Java人才时也会考察求职者诸如性能优化.高可用性.备份.集群.负载均衡.读写分离等问题. ...

  7. DF学Mysql(三)——Mysql数据类型

    Mysql数据类型分为:整数类型.浮点数类型.定点数类型日期与时间类型字符串类型二进制类型 整数类型 字节数 无符号数取值范围 有符号数取值范围TINYINT 1 0-255 -128-127SMAL ...

  8. DF学Mysql(三)——索引操作

    概要: 数据库对象索引其实与书的目录非常相似,主要是为了提高从表中检索数据的速度. 由于数据存储在数据库表中,所以索引是创建在数据库表对象上的,由表中的一个字段或多个字段生成的键组成,这些键存储在数据 ...

  9. 这半年时间学Mysql的总结

    一条sql语句的执行流程 select * from t where id=1 1.mysql执行一条查询语句的流程 1.1客户端输入用户名密码连接mysql服务器 1.2查询这条sql语句有没有对应 ...

  10. 《一起学mysql》4

    索引的使用   索引太少返回结果很慢,但是索引太多,又会占用空间.每次插入新记录时,索引都会针对变化重新排序   什么时候使用索引 1.where 从句中用到的字段  select * from tb ...

随机推荐

  1. spring的事件

    理论 异步的实现方式可以使用事件,或者异步执行: spring中自带了事件的支持,核心是ApplicationEventPublisher; 事件包括三个要点: 事件的定义: 事件监听的定义: 发布事 ...

  2. mysql - 锁及事务的认识

    mysql事务特性:一致性原子性隔离性持久性 //mysql 事务隔离级别 读未提交 读未提交的数据 读已提交 读已提交的数据 串行序列化 一个事务完成了再执行另一个事务 可重复读(数据库默认) 就算 ...

  3. LeetCode题解002:两数相加

    两数相加 题目 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字 如果,我们将这两个数相加起来,则会返回一个新的链表 ...

  4. h5本地存储登录页面实现记住密码功能

    <!DOCTYPE html> <html> <head> <title></title> </head> <style ...

  5. Qt Creator配置MSVC调试器

    安装完QT后会看到Qt Creator中的MSVC构建组件带有黄色的感叹号,那是因为没有调试器的原因.由于Qt-MSVC版本套件没有默认安装调试器, 需要我们自己手动下载安装. 根据官方文档http: ...

  6. BayaiM__Linux安装MySQL的两种方法

    BayaiM__Linux安装MySQL的两种方法     < 以下内容,纯属抄袭,如有雷同,爱咋咋地 >  阅读(21210) | 评论(4340) | 转发(5660) | 删除 编辑 ...

  7. Event事件、进程池与线程池、协程

    目录 Event事件 进程池与线程池 多线程爬取梨视频 协程 协程目的 gevent TCP服务端socket套接字实现协程 Event事件 用来控制线程的执行 出现e.wait(),就会把这个线程设 ...

  8. linux--top工具分析

    top分析工具详解 第一行:10:01:23 当前系统时间126 days, 14:29 系统已经运行了126天14小时29分钟(在这期间没有重启过)2 users 当前有2个用户登录系统   loa ...

  9. 【tf.keras】tf.keras模型复现

    keras 构建模型很简单,上手很方便,同时又是 tensorflow 的高级 API,所以学学也挺好. 模型复现在我们的实验中也挺重要的,跑出了一个模型,虽然我们可以将模型的 checkpoint ...

  10. python time和datetime常用写法格式

    python 的time和datetime常用写法 import time from datetime import datetime from datetime import timedelta # ...