索引和查询优化
 
为什么要索引?
想想我们上小学的时候是怎么查字典的,比方查 理想的 “理”,首先在索引里找到声母 “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. 恢复Chrome 78以上版本的地址栏https和www显示

    Google在Chrome不知道是脑子抽抽还是怎么回事,非要把https://www从地址栏中隐藏掉. htttps://www.pool.ntp.org就给你显示个pool.ntp.org,这分明就 ...

  2. 【洛谷2791】幼儿园篮球题(第二类斯特林数,NTT)

    [洛谷2791]幼儿园篮球题(第二类斯特林数,NTT) 题面 洛谷 题解 对于每一组询问,要求的东西本质上就是: \[\sum_{i=0}^{k}{m\choose i}{n-m\choose k-i ...

  3. python3的reload(sys)

    import sys reload(sys) sys.setdefaultencoding(‘utf-8’) 以上是python2的写法,但是在python3中这个需要已经不存在了,这么做也不会什么实 ...

  4. 如何使用npm的部分用法以及npm被墙的解决方法

    我们要明白我们使用的npm就是node中自带的包(模块)管理工具:借助NPM可以帮助我们快速安和管理依赖包,使Node与第三方模块之间形成了一个良好的生态系统. 我们可以直接输入npm,查看帮助引导: ...

  5. 高效取余运算(n-1)&hash原理探讨

    Java的HashMap源码中用到的(n-1)&hash这样的运算,查找发现这是一种高效的求余数的办法,但其中的原理是什么呢为什么可以这么做呢? 先上结论:假设被除数是x,对于除数是2n的取余 ...

  6. LinuxShell脚本——循环结构

    LinuxShell脚本——循环结构 摘要:本文主要学习了Shell脚本中的循环结构. while循环 基本语法 while循环是最简单的一种循环,如果条件满足则执行循环里的语句,如果条件不满足则退出 ...

  7. HTML颜色名称大全

    所有浏览器支持的颜色名称,所有现代浏览器都支持以下140种颜色名称(单击颜色名称或十六进制值,以将颜色视为背景颜色以及不同的文本颜色): 有关HTML颜色的完整概述,请访问我们的颜色教程. 颜色名称 ...

  8. [转]Outlook API

    本文转自:https://www.cnblogs.com/yl153/p/6711519.html 1.Outlook简介 若要从Outlook 外控制Outlook对象,必须在编写代码的工程中建立对 ...

  9. arcgis api for javascript 学习(六) 地图打印

    1.本文应用arcgis api for javascript对发布的动态地图进行打印,打印的为PDF格式,打印出来如图: 2.需要特别注意的是:我们在运行代码前,需要打开PrintingTools, ...

  10. C# 运行时的关系

    简介 记录c#对象在托管堆中运行时的相互关系,如下记录了一个方法在执行时候的生命周期,当方法在之前,CLR会先执行将方法里面所有用到的局部变量.参数对应的内存地址等全部存放当前线程栈当中,并且会将所有 ...