APP下载

MySQL详情

消息来源:baojiabao.com 作者: 发布时间:2024-05-17

报价宝综合消息MySQL详情

MySQL体系结构

例项

mysqld在启动时,自动派生master thread ------>生成工作的执行绪(read write 资源管理 等执行绪)

预分配内存区域

mysqld三层结构

DML:资料操作语言

DDL:数据库物件定义语言

DCL:资料控制语言

mysql三层结构

连线层

1、提供连线协议(TCP/IP socket)

2、验证的功能

3、提供一个专门的连线执行绪(接收使用者发来的SQL,执行完成之后返回最终结果,但是没有能力“看懂”SQL,会将SQL语句丢给下一层)

SQL层

1、接收上层发来语句

2、语法检查模组进行语法检查

3、语义的检查模组检查语义,分辨SQL语句的型别,将不同种类的语句交给不同的解析器。

4、解析器接收到SQL语句,进行解析操作,得到SQL的执行计划(explain)

5、优化器负责基于“成本”,找到消耗成本最低的执行计划。

6、执行器会基于优化器的选择,执行SQL语句,得到获取资料方法,交由下一层继续处理。

7、将二进位制或者16进位制资料,结构化成表

8、查询快取:SQL语句的hash值+资料结果 ------>redis

储存引擎层

根据上层次获取资料的方法,把资料提取出来

许可权管理

主机范围

10.0.0.% 10.0.0.1-10.0.0.254

10.0.0.5% 10.0.0.50-10.0.0.59

使用者名称@'主机范围' 主机范围被称之为白名单

grant all privileges on *.* to [email protected]'10.0.0.%' identified by '123';

grant 许可权 on 许可权作用范围 to 使用者 identified by '密码'

举例,授权给bbs专案的使用者一些许可权

grant create,update,insert,select ,CREATE VIEW on bbs.* to [email protected]'192.168.12.%' identified by '123';

all privileges

SELECT, INSERT, UPDATE, DELETE, CREATE, RELOAD,

SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER,

SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, DROP

LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT,

CREATE VIEW, SHOW VIEW, CREATE ROUTINE,

ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE

开发可能用到的许可权

create

update

insert

select

CREATE VIEW

CREATE ROUTINE

SHOW VIEW

CREATE TEMPORARY TABLES

ALTER

客户端工具中自带命令

1、h 或 help 或 ?

不知道某条语句如何书写时可检视完整写法,比如select语句你忘了整体结构,可以help select即可检视select完整语法结构

2、source

载入事先写好的MySQL档案,自动执行档案内的SQL操作

如何防止对资料的操作操作

使用TRIGGER触发器,在使用者对数据库进行增删改的的时候自动触发,控制使用者前后行为,主从复制

伪删除(灰度处理)

我们知道无论是对数据库还是资料,最好都不要轻易的删除,那么这个时候就会想到用伪删除的方式来实现相同的效果。

1.给每条资料额外增加一个status字段,用来表示该条资料的状态资讯即用update替代真正的delete

2.使用中介软件自动拦截来达到相同的效果即灰度处理

索引即执行计划

B树

也叫二叉搜寻树,

1.所有非叶子结点至多拥有两个儿子(Left和Right);

2.所有结点储存一个关键字;

这里我们需要知道的是,二分法的优缺点,优点是提高了查询效率,缺点是每一个被查询条件项被查询的概率并不相等,比如位于资料的首位项,用二分法效率就会很低,那么如何实现没想资料的查询概率都是平等的呢?下面的B+树和B*树就很好的解决了这个问题,并在范围查询方面进行了一定的优化处理

B+树

为所有叶子结点增加一个链指标,当查询语句是范围查询时,能规避掉走根节点和枝节点的消耗,直接从叶子节点的链指标走到下一行

B*树

是B+的变体,在B+树的枝结点再增加指向兄弟的指标,优化范围查询

MySQL查询资料

两种方式

全表扫描、索引扫描

通过explain命令的type可以看到,ALL的话就是全表扫描。

mysql在使用全表扫描时的效能是极其差的,所以MySQL尽量避免出现全表扫描

全表扫描什么时候出现?

1、业务确实要获取所有资料

2、不走索引,导致的全表扫描

2.1 没索引

2.2 索引建立有问题

2.3 语句有问题

如何检视查询型别

索引扫描有很多种级别,也是通过explain type能看到

type : 表示MySQL在表中找到所需行的方式,又称“访问型别”

常见型别如下:

index, range, ref, eq_ref, const system, Null

从左到右,效能从最差到最好,我们认为至少要达到range级别

1、index

Full Index Scan,index与ALL区别为index型别只遍历索引树

2、range

索引范围扫描,对索引的扫描开始于某一点,返回匹配值域的行。

显而易见的索引范围扫描是带有between或者where子句里带有查询。

where条件后 > =

我们在使用索引是,最低应当达到range

alter table city add index idx_popu(population);

explain select * from city where population >5000000;

explain select * from city where countrycode in ("CHN","JPN");

当mysql使用索引去查询一系列值时,例如IN()和OR列表,也会显示range(范围扫描),当然效能上面是有差异的。

explain select * from test where countrycode in ('chn','jpn');

改写为:

explain select * from city where countrycode='chn'

union

select * from city where countrycode='jpn';

3、ref

使用非唯一索引扫描或者唯一索引的字首扫描,返回匹配某个单独值的记录行

explain select * from test where countrycode='chn';

4、eq_ref

类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,

就是多表连线中使用primary key或者 unique key作为关联条件

A join B

on A.sid=B.sid

5、const、system

当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些型别访问。

如将主键置于where列表中,MySQL就能将该查询转换为一个常量

explain select * from city where id=1000;

6、NULL

MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,

例如从一个索引列里选取最小值可以通过单独索引查询完成。

数据库索引的设计原则

为了使索引的使用效率更高,在建立索引时,必须考虑在哪些字段上建立索引和建立什么型别的索引。

那么索引设计原则又是怎样的?

选择唯一性索引

唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录。

例如,学生表中学号是具有唯一性的字段。为该字段建立唯一性索引可以很快的确定某个学生的资讯。

如果使用姓名的话,可能存在同名现象,从而降低查询速度。

主键索引和唯一键索引,在查询中使用是效率最高的。

注意:如果重复值较多,可以考虑采用联合索引

经常需要排序、分组和联合操作的字段建立索引

经常需要ORDER BY、GROUP BY、DISTINCT和UNION等操作的字段,排序操作会浪费很多时间。

如果为其建立索引,可以有效地避免排序操作。

常作为查询条件的字段建立索引

如果某个字段经常用来做查询条件,那么该字段的查询速度会影响整个表的查询速度。因此,

为这样的字段建立索引,可以提高整个表的查询速度。

3.1 经常查询

3.2 列值的重复值少

注:如果经常作为条件的列,重复值特别多,可以建立联合索引。

尽量使用字首来索引

如果索引字段的值很长,最好使用值的字首来索引。例如,TEXT和BLOG型别的字段,进行全文检索

会很浪费时间。如果只检索字段的前面的若干个字元,这样可以提高检索速度。

不走索引的情况

1) 没有查询条件,或者查询条件没有建立索引

select * from tab; 全表扫描。

select * from tab where 1=1;

(1)select * from tab;

SQL改写成以下语句:

selec * from tab order by price limit 10 需要在price列上建立索引

(2)

select * from tab where name='zhangsan' name列没有索引

改:

1、换成有索引的列作为查询条件

2、将name列建立索引

2) 查询结果集是原表中的大部分资料,应该是30%以上。

查询的结果集,超过了总数行数30%,优化器觉得就没有必要走索引了。

假如:tab表 id,name id:1-100w ,id列有索引

select * from tab where id>500000;

如果业务允许,可以使用limit控制。

什么是业务: 产品的功能 + 使用者的行为

怎么改写 ?

结合业务判断,有没有更好的方式。如果没有更好的改写方案

尽量不要在mysql存放这个资料了。放到redis里面。

3) 索引本身失效,统计资料不真实

索引有自我维护的能力。

对于表内容变化比较频繁的情况下,有可能会出现索引失效。

4) 查询条件使用函式在索引列上,或者对索引列进行运算,运算包括(+,-,*,/,! 等)

例子:

错误的例子:select * from test where id-1=9;

正确的例子:select * from test where id=10;

5)隐式转换导致索引失效

这一点应当引起重视.也是开发中经常会犯的错误.

这样会导致索引失效:

例如使用者的手机号字段,你用的是varchar型别来储存,那么在以手机号为筛选条件时,手机号应该写为字串形式,而不是数值形式,虽然两者都能得出结果,但是如果数据库里面的型别与你输入的型别不一致,mysql会帮你自动转换,但是这个自动就需要用到的函式来实现,所以就不会走索引~~~

2019-07-18 14:51:00

相关文章