MySQL 学习心得和知识总结(一)

2019年5月6日 晚上,MySQL数据库学习第一节课:
MySQL学习内容如下:

1 mysql的介绍
2 sql语句,增删改查 CURD
3 索引以及原理
4 事务处理
5 存储引擎

文章目录

  • MySQL数据库的介绍
  • MySQL的卸载(Windows)
  • SQL语句使用
    • 1 开启服务;登录DBMS
    • 2 创建新的数据库:
    • 3 显示当前的所有数据库:
    • 4 使用数据库,以及查询数据库的 各表。
    • 5 建表:
    • 6 查看表的结构:
    • 7 查看创建表的sql语句,表的存储引擎以及编码格式
    • 8 插入数据
    • 9 查询数据
    • 10 按照分数score 查询数据
    • 11 按照分数score 排序:默认是 升序
    • 12 更新数据
    • 13 分组
    • 14 计数
    • 15 explain: 查看sql语句的执行计划
    • 16 建立索引
    • 17 建立联合索引(score name)
  • MySQL的语法规范
  • 知识点小结

MySQL数据库的介绍

------------------------------------------------分割线-------------------------------------------------------
使用数据库的优点:
1、可以(像文件一样)实现数据持久化到本地
2、使用完整的管理系统统一管理数据,易于查询

上面第一点的原因:实际上是借助于DBMS来将数据最终存储到磁盘上的文件。

数据库的相关概念:
DB:数据库,存放数据的仓库(容器),它保存了一系列有组织,比较规范的数据。
DBMS:数据库管理系统(简称:数据库软件、数据库产品。如MySQL)。数据库是通过DBMS创建和操作的容器,DBMS用来管理DB中的数据。(DBMS用于创建和管理DB)

上面二者关系,如下图所示:MySQL 学习心得和知识总结(一)_第1张图片
SQL:结构化查询语言,专门用来与数据库管理系统通信的语言。
SQL的优点:

  • 不是某个特定数据库供应商的专门语言,而是几乎所有的DBMS都支持SQL
  • 简单易学
  • 虽然简单,但是实际上是一种强有力的语言,灵活使用其语言元素,可以进行非常复杂和高级的数据库操作

数据库的特点:

  • 将数据放到表里面,表再放到库中(库里面可以有很多表)
  • 一个数据库里面可以有多张表,每个表都有一个名字,用来标识自己。表名具有唯一性。
  • 表具有一些特性,这些特性定义了数据在表中如何存储的,类似于Java中的类的设计。
  • 表是由列组成的,也称为字段。所有表都是由一个或多个列组成的,每个列相当于Java中的“属性”。
  • 表中的数据是按行存储的,每一行类似于Java中的“对象”。

DBMS分为两大类:

  • 基于共享文件系统的DBMS(Access)
  • 基于C/S的DBMS(如:MySQL、oracle、SQL Server)

------------------------------------------------分割线-------------------------------------------------------
MySQL现隶属于 oracle公司
1 它是关系型数据库的一种。
2 它是个RDBMS 关系型数据库管理系统=》创建很多数据库 =》二维表
SQL(Structed Query Language)语句
二维表 行:记录 列:属性/字段

关系型数据库有:(常见的数据库管理系统)
oracle:贵
MySQL: 企业版(收费的) 社区版(免费的) MySQL
SQL Server 其最大的缺点:只能安装在Windows上
DB2(IBM公司):其稳定性 性能上不错的,适合于处理海量数据

非关系型数据库 NoSQL [key, value] 有:
1 memcached(不能持久化)
2 redis(可以持久化数据)缓存数据库

可以看一下MySQL在市场上的应用比例:MySQL 学习心得和知识总结(一)_第2张图片
MySQL产品的特点: 优点:

  • 成本低,开放源代码,一般可以免费使用
  • 性能高:执行很快,且移植性好
  • 简单:体积小,容易安装和使用

------------------------------------------------分割线-------------------------------------------------------
关系型数据库:指采用了关系模型来组织数据的数据库,而关系模型指的就是二维表模型,而一个关系型数据库就是由二维表及其之间的联系所组成的一个数据组织。
关系型数据库的优势

  1. 容易理解:二维表结构是非常贴近逻辑世界的一个概念,关系模型相对网状、层次等其他模型来说更容易理解
  2. 使用方便:通用的结构化查询语言使得操作关系型数据库非常方便
  3. 易于维护:丰富的完整性(实体完整性、参照完整性和用户自定义完整性)大大减低了数据冗余和数据不一致的概率

非关系型数据库,又被称为NoSQL(Not Only SQL )意为不仅仅是SQL,指非关系型的,分布式的,且一般不保证遵循ACID原则的数据存储系统。

非关系型数据库以键值对存储,且结构不固定,每一个元组(记录)可以有不一样的字段,每个元组可以根据需要增加一些自己的键值对,不局限于固定的结构,可以减少一些时间和空间的开销。

------------------------------------------------分割线-------------------------------------------------------

MySQL的卸载(Windows)

MySQL 学习心得和知识总结(一)_第3张图片
打开注册表:regedit (cmd里面)
------------------------------------------------分割线-------------------------------------------------------
MySQL:为什么说它是分布式的关系型数据库管理系统?
答:它不是一个单机的数据库,mysql client和mysql server,所以在使用的时候 需要安装client 和 server,server比较重要(数据存储的地方)。所以说 常说的安装数据库指的是 安装server端。

  1. 首先得启动mysql server
  2. 通过mysql client和server建立tcp链接
  3. mysql client就可以通过创建得连接发送sql语句到mysql server上
  4. mysql server处理完sql语句,把结果返回到mysql client和mysql
  5. 关闭当前mc和ms的链接

mysql client:api接口 适用于c&c++ java python php go

mysql server作为一个网络服务器,采用得网络模型是:
select + 线程池得模型 >> 磁盘得I/O速率
question:采用得网络模型是:epoll + 线程池得模型 ?
因为:>> 磁盘得I/O速率,最好的不一定是最合适的。
linux:epoll windows:iocp

------------------------------------------------分割线-------------------------------------------------------
在服务端安装好了以后,这里面就相当于 维护了一个大容器(大仓库),但是可能默认是关闭状态,即使有权限和身份 也是进不去的。所以在使用前,需要保证服务是启动的状态。
windows上在任务管理器 - 服务 - 启动 MySQL(安装时 的服务名)
MySQL 学习心得和知识总结(一)_第4张图片
上面的打开服务,略显太慢。MySQL 学习心得和知识总结(一)_第5张图片
以管理员身份打开DOS,然后net start mysql启动服务:MySQL 学习心得和知识总结(一)_第6张图片
接下来关闭服务:net stop mysqlMySQL 学习心得和知识总结(一)_第7张图片

打开mysql command line - unicode命令行窗口输入密码就可以登录MySQL server
MySQL 学习心得和知识总结(一)_第8张图片
上面这种登录方式 只适合root用户,下面一种也是可以的(Windows的命令提示符 管理员运行 ):(这样也可以显示密码登录)MySQL 学习心得和知识总结(一)_第9张图片
linux先启动mysqld /etc/init.d/mysqld start/stop/restart
netstat -tanp 查看以下mysqld服务是否启动成功
mysql -u root -p密码

退出是 exit 或者 Ctrl+c即可
登录的是DBMS

------------------------------------------------分割线-------------------------------------------------------
show databases;//显示有哪些数据库
use mysql;//选用一个数据库
show tables;//看里面有哪些表
desc user; // 查看表的结构
show create table user; // => 查看创建表得sql语句,表得存储引擎以及编码格式

注:假如我们use mysql;选择这个数据库,然后show tables from test;那么我现在其实还是在mysql库里面 只是查看了一下test的表。

// 创建数据库
create database tulun;
// 删除数据库
drop databases tulun;

// 选择数据库
use tulun; // show tables;

//看一下数据库服务器版本号:
select version();
或者用下面的这两个DOS命令:
mysql --version
mysql -V

//看一下 现在我位于哪个数据库
select database();

// 创建一张学生表 id int name varchar age int sex enum score double level “”
// 字段名称+字段类型+字段得完整性约束条件(主键,外键,unique,not null, default, auto_increment)
create table student(id int primary key,
name varchar(20), age tinyint,
sex enum(‘男’, ‘女’), score double,
level varchar(20) default “不合格”);

// 删除表
drop table student;

// insert
insert into student values();

// delete
delete fron student where score < 60.0 or age < 20;

// update
update student set level=“合格” where score > 90.0;

// select 单表得查询和多表得查询
select * from student;
select id,name,score,level front student;
select * from student where score>60.0;
select name,age,sex where level = ‘合格’;

SQL得排序order by 字段名称 asc(默认)/desc 和
分组group by 字段名称 经常和mysql得函数一起使用,得到分组后得详细情况

索引的sql语句 很多学生10000记录 name : zhang san
name字段创建一个索引,mysql server会把表中所有记录的name字段的值进行排序 进行一个二分搜索
create index name_index on student(name);
注意:
1.对区分度高的字段创建索引好;对区分度低的字段不用创建索引了。
2.MySQL Server使用索引的时候,会进行索引优化,如果过滤字段需要搜索表的数据达到60-70%,索引就
被放弃了,执行整表搜索了。
3.如果过滤条件+排序或者分组条件,此时最好创建联合索引
4.对于一张表的一次查询只能用到一个索引
《MySQL索引漫画》

带in的子查询: <=== 为什么多表联合查询时,不建议使用带in子查询,都要写成连接查询,为甚?
select * from
Employeeaddress
where addreddID
in (select AddressID from Employee where EmployeeId=10000)

熟悉单表的CURD,排序和分组,字段创建索引,explain查看SQL执行计划,
连接查询:内连接和外连接查询(左连接和右连接)
select b.country,b.city,b.street
from
Employee a, Employeeaddress b
on a.AddressID = b.addreddID
where a.EmployeeId = 10000;

===> 同样的内连接SQL语句是:
select b.country,b.city,b.street
from
Employee a
inner join
Employeeaddress b
on a.AddressID = b.addreddID
where a.EmployeeId = 10000;

explain: 查看sql语句的执行计划

》》》 了不了解数据库得范式设计???
范式一、范式二、范式三、BC范式、范式四

范式:减少表得冗余,防止数据不一致,提高数据的查询效率;范式越多,表划分的就越多,多表
联合查询的次数就越多,查询的效率就会变慢! 因此范式绝对不是越高越好,一般数据库表的
设计达到范式三就足够了!

student 1000行
id name sex age 选择的课程 课程的总成绩 学生的考试成绩
1 zhang male 20 语文 100 98
------------------------------------------------分割线-------------------------------------------------------

下面是《MYSQL入门很简单的第六章》

SQL语句使用

一、DQL语言:数据查询语言。主要是针对select操作
二、DML语言:数据操作语言,主要是针对 增删改操作
三、DDL语言:数据定义语言,主要是针对表 库的定义操作
四、TCL语言:事务控制语言,主要是针对 事务和事务的处理

1 开启服务;登录DBMS

MySQL 学习心得和知识总结(一)_第10张图片

2 创建新的数据库:

在这里插入图片描述

3 显示当前的所有数据库:

MySQL 学习心得和知识总结(一)_第11张图片

4 使用数据库,以及查询数据库的 各表。

现在我尚未建表,当然为空。
在这里插入图片描述

5 建表:

在这里插入图片描述
MySQL 学习心得和知识总结(一)_第12张图片
修改表名:
MySQL 学习心得和知识总结(一)_第13张图片
修改字段/属性的属性类型:
MySQL 学习心得和知识总结(一)_第14张图片
上面的错误例子如下:
MySQL 学习心得和知识总结(一)_第15张图片
修改属性名:MySQL 学习心得和知识总结(一)_第16张图片
表内增加一个新的字段:
MySQL 学习心得和知识总结(一)_第17张图片
表内删除一个字段:(把上面的那个Stest字段删除)
MySQL 学习心得和知识总结(一)_第18张图片
将一个字段放到表的首位去:
MySQL 学习心得和知识总结(一)_第19张图片
将一个字段1放到字段2的后面:
MySQL 学习心得和知识总结(一)_第20张图片
修改表的存储引擎:
MySQL 学习心得和知识总结(一)_第21张图片
MySQL 学习心得和知识总结(一)_第22张图片

6 查看表的结构:

MySQL 学习心得和知识总结(一)_第23张图片
MySQL 学习心得和知识总结(一)_第24张图片

7 查看创建表的sql语句,表的存储引擎以及编码格式

MySQL 学习心得和知识总结(一)_第25张图片
MySQL 学习心得和知识总结(一)_第26张图片
MySQL 学习心得和知识总结(一)_第27张图片

8 插入数据

MySQL 学习心得和知识总结(一)_第28张图片
以下面为准:
在这里插入图片描述
MySQL 学习心得和知识总结(一)_第29张图片
主键可以自增;level 是有默认值的
MySQL 学习心得和知识总结(一)_第30张图片
一条语句,插入多条记录。

9 查询数据

MySQL 学习心得和知识总结(一)_第31张图片
MySQL 学习心得和知识总结(一)_第32张图片
把指定字段的一定范围的数据给查询出来:
MySQL 学习心得和知识总结(一)_第33张图片
把年龄大于21的信息都给打印出来:
MySQL 学习心得和知识总结(一)_第34张图片
上图也可以如下:
MySQL 学习心得和知识总结(一)_第35张图片
把年龄在20到21之间的信息查询出来:
MySQL 学习心得和知识总结(一)_第36张图片
把姓司马的狗东西 都查出来:
MySQL 学习心得和知识总结(一)_第37张图片
把名字里面有 炎 的信息查出来:
MySQL 学习心得和知识总结(一)_第38张图片
把名字里面 第二个字是 炎的信息查询出来
在这里插入图片描述
把名字为空的信息给打印出来:
MySQL 学习心得和知识总结(一)_第39张图片
下面是 带and的多条件查询:
把姓司马的 而且 还是女的给查出来:
MySQL 学习心得和知识总结(一)_第40张图片
把姓司马的 或者 姓曹的查询出来:
MySQL 学习心得和知识总结(一)_第41张图片
把表中 年龄的去重给打印出来:
MySQL 学习心得和知识总结(一)_第42张图片

10 按照分数score 查询数据

MySQL 学习心得和知识总结(一)_第43张图片

11 按照分数score 排序:默认是 升序

SQL得排序order by 字段名称 asc(默认)/desc
MySQL 学习心得和知识总结(一)_第44张图片
MySQL 学习心得和知识总结(一)_第45张图片
MySQL 学习心得和知识总结(一)_第46张图片

12 更新数据

MySQL 学习心得和知识总结(一)_第47张图片
下面是删除一行数据:
MySQL 学习心得和知识总结(一)_第48张图片

13 分组

分组group by 字段名称 经常和mysql得函数一起使用,得到分组后得详细情况
MySQL 学习心得和知识总结(一)_第49张图片
按照性别分组,然后把姓宋的这个帅气的天才给查出来:
MySQL 学习心得和知识总结(一)_第50张图片

14 计数

MySQL 学习心得和知识总结(一)_第51张图片
MySQL 学习心得和知识总结(一)_第52张图片
MySQL 学习心得和知识总结(一)_第53张图片

15 explain: 查看sql语句的执行计划

没有索引 它5行全查了一遍
MySQL 学习心得和知识总结(一)_第54张图片

16 建立索引

索引的sql语句 很多学生10000记录 name : zhang san
name字段创建一个索引,mysql server会把表中所有记录的name字段的值进行排序 进行一个二分搜索
create index name_index on student(name);
注意:
1.对区分度高的字段创建索引好;对区分度低的字段不用创建索引了。
2.MySQL Server使用索引的时候,会进行索引优化,如果过滤字段需要搜索表的数据达到60-70%,索引就
被放弃了,执行整表搜索了。
3.如果过滤条件+排序或者分组条件,此时最好创建联合索引
4.对于一张表的一次查询只能用到一个索引

建立姓名name索引:
MySQL 学习心得和知识总结(一)_第55张图片
建议姓名索引后的情形:只用查询一行
MySQL 学习心得和知识总结(一)_第56张图片
------------------------------------------------分割线-------------------------------------------------------
下面是建立 level索引的情形:
在这里插入图片描述
MySQL 学习心得和知识总结(一)_第57张图片
上图显示:有索引,可是MySQL并没有用。
------------------------------------------------分割线-------------------------------------------------------
建立 score索引:
MySQL 学习心得和知识总结(一)_第58张图片
------------------------------------------------分割线-------------------------------------------------------
如果过滤条件+排序或者分组条件,此时最好创建联合索引
对于一张表的一次查询只能用到一个索引。这里虽然 score 和 name都有索引,但只能用 score_index
MySQL 学习心得和知识总结(一)_第59张图片
过滤条件是 score;score是排序条件。要建立联合索引,首先撤除两个索引:
在这里插入图片描述
删除两个索引成功:
MySQL 学习心得和知识总结(一)_第60张图片

17 建立联合索引(score name)

MySQL 学习心得和知识总结(一)_第61张图片
MySQL 学习心得和知识总结(一)_第62张图片
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
下面是多表查询的操作:
MySQL 学习心得和知识总结(一)_第63张图片
成绩表:为学生学号、课程号、成绩

现在要对这两个表要进行联合查询:(通过相同字段SID)
左连接:left join
右链接 :right join
内连接: inner join

看一下左连接:
MySQL 学习心得和知识总结(一)_第64张图片
分析如上:学生表在左,成绩表在右。返回的是左边表的所有数据以及右边表的(通过相同字段连接起来的)相同的数据。因此左边存在 而右边不存在的则全部就成了 NULL。

看一下右链接:
MySQL 学习心得和知识总结(一)_第65张图片
分析如上:学生表在左,成绩表在右。返回的是右边表的所有数据以及左边表的(通过相同字段连接起来的)相同的数据。
看一下内连接:在这里插入图片描述
分析如上:学生表通过内连接来连接成绩表。也是学生表在左,成绩表在右。返回的是左右两表都同时存在的数据(通过相同字段连接起来的)。(内连接是连个表同时存在的数据)

例子如下:

  1. 把已存在的学生 已有成绩的 姓名、学号、成绩打印出来:(内连接的应用)
    MySQL 学习心得和知识总结(一)_第66张图片
    MySQL 学习心得和知识总结(一)_第67张图片
    2.后面的结果 再进行子表查询MySQL 学习心得和知识总结(一)_第68张图片
  2. 把第一个表和第二个表的信息 联合查询(同一个属性的数据。联合查询默认的结果数据进行了去重,使用all可以展示不去重的结果)
    MySQL 学习心得和知识总结(一)_第69张图片
    不加all的话,那么它就会自动去进行一个 去重操作。就是1到11了。
  3. limit 分页查询
    MySQL 学习心得和知识总结(一)_第70张图片
    第一种:默认是从首行开始的,参数 值 的是读取数据的长度/个数(若是没有那么多 则全部读取出来即可)。
    第二种:第一个位置的值是起始位置,第二个参数 值 的是读取数据的长度/个数(若是没有那么多 则全部读取出来即可)。
  4. sum函数的使用:
    MySQL 学习心得和知识总结(一)_第71张图片
  5. avg函数的使用:(求平均数)
    MySQL 学习心得和知识总结(一)_第72张图片
  6. max和min函数的使用:
    MySQL 学习心得和知识总结(一)_第73张图片

MySQL的语法规范

  1. 不区分大小写,但建议:关键字大写、表名列名小写
  2. 每一条SQL命令 最好用;结尾。\g也行
  3. 每条命令可以根据需要,进行缩进或者换行
  4. 注释
    4.1 单行注释:#注释文字
    4.2 单行注释:-- (这有一个空格)注释文字
    4.3 多行注释:/* 注释文字 */

知识点小结

《MySQL索引漫画》
使用索引时,有以下一些技巧和注意事项:
(1)越小的数据类型通常更好:越小的数据类型通常在磁盘、内存和CPU缓存中都需要更少的空间,处理起来更快。
(2)简单的数据类型更好:整型数据比起字符,处理开销更小,因为字符串的比较更复杂。在MySQL中,应该用内置的日期和时间数据类型,而不是用字符串来存储时间;以及用整型数据类型存储IP地址。
(3)尽量避免NULL:应该指定列为NOT NULL,除非你想存储NULL。在MySQL中,含有空值的列很难进行查询优化,因为它们使得索引、索引的统计信息以及比较运算更加复杂。你应该用0、一个特殊的值或者一个空串代替空值。
(4)索引不会包含有NULL值的列。

但是如果是同样的sql如果在之前能够使用到索引,那么现在使用不到索引,以下几种主要情况:

  1. 随着表的增长,where条件出来的数据太多,大于15%,使得索引失效(会导致CBO计算走索引花费大于走全表)

  2. 统计信息失效 需要重新搜集统计信息

  3. 索引本身失效 需要重建索引

下面是一些不会使用到索引的原因
索引失效

  1. 没有查询条件,或者查询条件没有建立索引;
  2. 在查询条件上没有使用引导列
  3. 查询的数量是大表的大部分,应该是30%以上。
  4. 索引本身失效
  5. 查询条件使用函数在索引列上(见12)
  6. 对小表查询
  7. 提示不使用索引
  8. 统计数据不真实
  9. CBO计算走索引花费过大的情况。其实也包含了上面的情况,这里指的是表占有的block要比索引小。
    10)隐式转换导致索引失效.这一点应当引起重视.也是开发中经常会犯的错误. 由于表的字段tu_mdn定义为varchar2(20),
    但在查询时把该字段作为number类型以where条件传给mysql,这样会导致索引失效.
    错误的例子:select * from test where tu_mdn=13333333333;
    正确的例子:select * from test where tu_mdn=‘13333333333’;
    11)对索引列进行运算导致索引失效,我所指的对索引列进行运算包括(+,-,*,/,! 等)
    错误的例子:select * from test where id-1=9;
    正确的例子:select * from test where id=10;
    12)使用mysql内部函数导致索引失效.对于这样情况应当创建基于函数的索引.
    错误的例子:select * from test where round(id)=10;
    说明,此时id的索引已经不起作用了 正确的例子:首先建立函数索引,
    create index test_id_fbi_idx on test(round(id));
    然后 select * from test where round(id)=10; 这时函数索引起作用了

13)如果MySQL估计使用索引比全表扫描更慢,则不使用索引。例如如果列key_part1均匀分布在1到100之间,查询时使用索引就不是很好

mysql>select * from table_name where key_part1>1 and key_part<90;

14)如果使用MEMORY/HEAP表并且where条件中不使用“=”进行索引列,那么不会用到索引。Heap表只有在“=”的条件下会使用索引。因为用的是哈希索引。

15)用or分割开的条件,如果or前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到。

表见mysql索引之五:组合索引怎么应该怎么选取引导列

mysql> show index from test1\G;
*************************** 1. row ***************************
        Table: test1
   Non_unique: 1
     Key_name: inx_id_name
 Seq_in_index: 1
  Column_name: name
    Collation: A
  Cardinality: 552589
     Sub_part: NULL
       Packed: NULL
         Null: YES
   Index_type: BTREE
      Comment: 
Index_comment: 
*************************** 2. row ***************************
        Table: test1
   Non_unique: 1
     Key_name: inx_id_name
 Seq_in_index: 2
  Column_name: id
    Collation: A
  Cardinality: 567855
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
rows in set (0.00 sec)

ERROR: 
No query specified

mysql>

从上面可以发现只有name和id列上面有索引。来看如下的执行计划。

mysql> explain extended select * from test1 where name='name100' or dept='dept100';
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------------+
|  1 | SIMPLE      | test1 | NULL       | ALL  | inx_id_name   | NULL | NULL    | NULL | 769014 |    19.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------------+
row in set, 2 warnings (0.00 sec)

mysql>

16)如果将要使用的索引列不是复合索引列表中的第一部分,则不会使用索引

如下例子:可见虽然在id上面建有复合索引,但是由于id不是索引的第一列,那么在查询中这个索引也不会被MySQL采用。

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

mysql>

17)如果like是以%开始,可见虽然在name上面建有索引,但是由于where 条件中like的值的“%”在第一位了,那么MySQL也会采用这个索引。

如果WHERE子句的查询条件里使用了比较操作符LIKE和REGEXP,MYSQL只有在搜索模板的第一个字符不是通配符的情况下才能使用索引。比如说,如果查询条件是LIKE ‘abc%’,MYSQL将使用索引;如果条件是LIKE ‘%abc’,MYSQL将不使用索引。

18)独立的列(对列变量需要计算(聚合运算、类型转换等))

独立的列是指索引列不能是表达式的一部分,也不是是函数的参数。例如以下两个查询无法使用索引:

1)表达式: select actor_id from sakila.actor where actor_id+1=5;

2)函数参数:select … where TO_DAYS(CURRENT_DATE) - TO_DAYS(date_col)<=10;应该把列计算转换成常量计算。

示例:

如果列类型是字符串,但在查询时把一个数值型常量赋值给了一个字符型的列名name,那么虽然在name列上有索引,但是也没有用到。

mysql> explain select * from company2 where name=294\G 
*************************** 1. row *************************** 
id: 1 
select_type: SIMPLE 
table: company2 
type: ALL 
possible_keys: ind_company2_name 
key: NULL 
key_len: NULL 
ref: NULL 
rows: 1000 
Extra: Using where 
row in set (0.00 sec)

而下面的sql语句就可以正确使用索引。

mysql> explain select * from company2 where name name=‘294'\G 
*************************** 1. row *************************** 
id: 1 
select_type: SIMPLE 
table: company2 
type: ref 
possible_keys: ind_company2_name 
key: ind_company2_name 
key_len: 23 
ref: const 
rows: 1 
Extra: Using where 
row in set (0.00 sec)

19).在JOIN操作中(需要从多个数据表提取数据时),MYSQL只有在主键和外键的数据类型相同时才能使用索引,否则即使建立了 索引也不会使用

20).在ORDER BY操作中,MYSQL只有在排序条件不是一个查询条件表达式的情况下才使用索引。尽管如此,在涉及多个数据表的查询里,即使有索引可用,那些索引在加快ORDER BY操作方面也没什么作用。

21).不要给“性别”增加索引。如果某个数据列里包含着许多重复的值,就算为它建立了索引也不会有很好的效果。比如说,如果某个数据列里包含了净是些诸如“0/1”或“Y/N”等值,就没有必要为它创建一个索引。

简单的说吧,不需要,因为性别,就两个值男与女(人妖不算,呵)。为这两个值建立索引是不值得的,因为无论多少条记录,建立性别的索引,最多让你的语句少检索一半。但与建立索引带来的损失比,捡芝麻丢西瓜。(可能不准确,但大意如些)。

打个比方,数据库就好比一本新华字典,我们查数据时,可以根据拼音来查,字在字典的排序是根据拼音来排序的,我们要查一个字,可以根据拼音很快就能查到我们要查的字,这就叫作聚集索引!换句话说,聚集索引就是按照物理排序的,也因为是按物理排序的,所以一张表只能有一个聚集索引,也是最快的索引。当然,我们也可以根据部首来查,但是这种查询必须先查找到部首,然后再到检索表查到那么字,最后才能查到我们需要的字,你没办法像拼音查法一样翻翻字典就可以查到,这就叫作普通索引。普通索引可以有多个。

假如一本字典里全是"男"和"女"两个字,那么在检索表里也有很多个"男"和"女",这对查询帮助不大。

22).如果对大的文本进行搜索,使用全文索引而不使用like“%…%”.

23).如果列名是索引,使用column_name is null将使用索引。

如下

mysql> explain select * from company2 where name is null\G 
*************************** 1. row *************************** 
id: 1 
select_type: SIMPLE 
table: company2 
type: ref 
possible_keys: ind_company2_name 
key: ind_company2_name 
key_len: 11 
ref: const 
rows: 1 
Extra: Using where 
row in set (0.00 sec)

24).不使用NOT IN和<>操作
NOT IN和<>操作都不会使用索引将进行全表扫描。NOT IN可以NOT EXISTS代替,id<>3则可使用id>3 or id<3来代替。

25).排序的索引问题
mysql查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。

26).使用短索引
对串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个CHAR(255)的列,如果在前10个或20个字符内,多数值是惟一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。

27).索引不会包含有NULL值的列
只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL。

28).使用ENUM而不是字符串

ENUM保存的是TINYINT,别在枚举中搞一些“中国”“北京”“技术部”这样的字符串,字符串空间又大,效率又低。

以上第三部分 来自于博客:
https://www.cnblogs.com/duanxz/p/5244703.html

你可能感兴趣的:(MySQL的学习心得和知识总结)