索引和查询优化
 
为什么要索引?
想想我们上小学的时候是怎么查字典的,比方查 理想的 “理”,首先在索引里找到声母 “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. vscode开发微信小程序使用less(插件Easy WXLESS)

    1.搜索按照Easy WXLESS 2.在文件中加入下面的一行代码:就会在同级目录下同步代码到.wss // out: index.wxss 更多的写法可以查官网:https://marketplac ...

  2. 【分布式存储】Glusterfs快速搭建

    目录 环境准备 步骤1,保证至少有三台服务器 步骤2,格式化和配置硬盘 步骤3,安装GlusterFS 步骤4,配置防火墙 步骤5,配置 trusted pool 步骤6,设置GlusterFS卷 步 ...

  3. Alpine Linux 安装 lxml Pillow 失败

    lixm 需要编译安装,因此需要先安装gcc g++ RUN apk add --update --no-cache g++ gcc libxslt-dev python3-dev openssl-d ...

  4. WPF 修改Webbrowser的IE版本小程序(32位)

    偶尔用Winform的Webbrowser,但是ie版本太低. 手改改注册表了太慢了. 弄个了程序,修改的代码时网上的,自己就是写了个界面. 支持IE11. XAML页面代码 <Window.R ...

  5. 从新手小白到老手大白的成长之路第二弹-WPF之UI界面之Grid面板

    废话不多说,接下来直接开始介绍WPF-UI界面-Grid面板 如图就是创建好了的一个WPF项目,整个界面被一个Window窗体包含起来,上面类似于什么什么网址什么的其实就相当于.net的命名空间,缺什 ...

  6. Python中最常见的10个问题(list)

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 大熊 PS:如有需要Python学习资料的小伙伴可以加点击下方链接 ...

  7. 一个小事例,了解golang通道阻塞模式

    在学习golang中,channel真的是让人捉摸不透的东西,本来我自以为我理解了协程阻塞的用法了,结果就下面这个小例子,我还是在打印输出后才搞明白到底怎么回事? 当然了,这也是我自身对协程这块不太熟 ...

  8. python数据可视化简介(一)

    目录 一:配置jupyter notebook 二:Matplotlib图像实例   数据可视化是用图形或者表格的形式进行数据显示,用图形化的手段,清晰有效地传递与沟通信息.既要保证直观易分析,又要保 ...

  9. AQS(抽象队列同步器)

    AQS(全称为AbstractQueuedSynchronizer),即抽象队列同步器,它维护了一个volatile int state(代表共享资源)和一个FIFO线程等待队列. state的访问方 ...

  10. JS基础语法---for循环遍历数组

    for循环遍历数组 要显示数组中的每个数据,可以如下: var arr=[10,20,30,40,50]; //显示数组中的每个数据 console.log(arr[0]); console.log( ...