索引和查询优化
 
为什么要索引?
想想我们上小学的时候是怎么查字典的,比方查 理想的 “理”,首先在索引里找到声母 “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. python-13-集合增删查

    前言 集合:可变的数据类型,但元素必须是不可变的数据类型,无序不重复,既可哈希.所以python的集合是不能进行修改的,只有增删查.可哈希.不可变数据类型有:元组.bool.int.str 一.增 1 ...

  2. LeetCode 205:同构字符串 Isomorphic Strings

    题目: 给定两个字符串 s 和 *t*,判断它们是否是同构的. 如果 s 中的字符可以被替换得到 *t* ,那么这两个字符串是同构的. 所有出现的字符都必须用另一个字符替换,同时保留字符的顺序.两个字 ...

  3. IT兄弟连 HTML5教程 了解HTML5的主流应用3

    5  基于HTML5的移动APP开发 不同的操作系统中,需要安装用不同技术开发的APP,移动端的操作系统有很多种,但最主要有两大分支,一种在苹果iOS操作系统中使用Objective-C语言开发APP ...

  4. kafka 重放 重播 从某个时间点或者offset开始消费

    转自: https://www.jianshu.com/p/932663e9a226 consumer.subscribe(topicA); consumer.poll(100);//正常订阅topi ...

  5. PHP fastcgi_finish_request 方法

    本文介绍,PHP运行在FastCGI模式时,FPM提供的方法:fastcgi_finish_request. 在说这个方法之前,我们先了解PHP有哪些常用的运行模式? PHP运行模式 CGI 通用网关 ...

  6. 【前端知识体系-NodeJS相关】浅谈NodeJS中间件

    1. 中间件到底是个什么东西呢? [!NOTE] 中间件其是一个函数,在响应发送之前对请求进行一些操作 function middleware(req,res,next){ // 做该干的事 // 做 ...

  7. win7和win10自带桌面便签哪里找

    一些小伙伴习惯使用windows自带的便签功能,但win7和win10区别较大, 导致更新系统后不知道在哪里找,甚至以为没有该功能了, 其实不然,下面我总结了2种方法,希望能帮到有需要的人 win7( ...

  8. 基于 HTML5 WebGL 构建智能城市 3D 场景

    前言 随着城市规模的扩大,传统的方式很难彻底地展示城市的全貌,但随着 3D 技术的应用,出现了 3D 城市群的方式以动态,交互式地把城市全貌呈现出来.配合智能城市系统,通过 Web 可视化的方式,使得 ...

  9. oracle trunc 日期 数字 的使用例子

    /**************日期********************/1.select trunc(sysdate) from dual --2013-01-06 今天的日期为2013-01-0 ...

  10. MySQL for OPS 10:MyCAT 分布式架构

    写在前面的话 在学习的索引的时候,有提到,当数据表数据达到 800W 的时候,索引的性能就开始逐步下降.对于一个公司而言,主要业务数据表达到 1000W 都很容易.同时这张表一般都是业务常用的表,操作 ...