- 执行流程图
- 基本的SQL语句
- 性能优化
- 索引
- 存储引擎
- 分库分表
- 主从同步机制
- 读写分离
一、 执行流程图
二、基本的SQL语句
- 创建用户
CREATE USER name IDENTIFIED BY 'ssapdrow'; - 修改密码
SET PASSWORD FOR name=PASSWORD('fdddfd'); - 查看name用户权限
SHOW GRANTS FOR name; - 给name用户db_name数据库的所有权限
GRANT SELECT ON db_name.* TO name; - 去除权限
REVOKE SELECT ON db_name.* TO name;, - 查看数据库:
SHOW DATABASES; - 创建数据库:
CREATE DATABASE db_name; - 使用数据库:
USE db_name; - 删除数据库:
DROP DATABASE db_name; - 复制表:
CREATE TABLE tb_name2 SELECT * FROM tb_name - 创建临时表:
CREATE TEMPORARY TABLE tb_name(这里和创建普通表一样); - 查看数据库中可用的表:
SHOW TABLES; - 查看表的结构:
DESCRIBE tb_name;SHOW COLUMNS in tb_name; //from也可以 - 表重命名:
RENAME TABLE name_old TO name_new;还可以使用:ALTER TABLE name_old RENAME name_new; - 删除表:
DROP [ TEMPORARY ] TABLE [ IF EXISTS ] tb_name[ ,tb_name2.......]; - 添加字段
ALTER TABLE tb_name ADD COLUMN address varchar(80) NOT NULL; - 插入数据:
INSERT INTO tb_name(id,name,score)VALUES(NULL,'张三',140),(NULL,'张四',178),(NULL,'张五',134); - 更新数据:
UPDATE tb_name SET score=189 WHERE id=2; - 插入检索出来的数据:
INSERT INTO tb_name(name,score) SELECT name,score FROM tb_name2; - 创建索引
CREATE INDEX index_name ON tb_name (column [ ASC | DESC ] , .......); - UNION规则——可以执行两个语句(可以去除重复行)
- 函数
字符串链接——CONCAT()
SELECT CONCAT(name,'=>',score) FROM tb_name
数学函数:
AVG、SUM、MAX、MIN、COUNT;
文本处理函数:
TRIM、LOCATE、UPPER、LOWER、SUBSTRING
运算符:
+、-、*、
时间函数:
DATE()、CURTIME()、DAY()、YEAR()、NOW()..... - REGEXP的正则表达式:
SELECT * FROM tb_name WHERE name REGEXP '^[A-D]' //找出以A-D 为开头的name、特殊字符需要转义。 - 条件控制:
WHERE 语句:
SELECT * FROM tb_name WHERE id=3;
HAVING 语句:
SELECT * FROM tb_name GROUP BY score HAVING count(*)>2
相关条件控制符:
=、>、<、<>、IN(1,2,3......)、BETWEEN a AND b、NOT
AND 、OR
Linke()用法中 % 为匹配任意、 _ 匹配一个字符(可以是汉字)
IS NULL 空值检测 - 全文检索——MATCH和AGAINST
SELECT MATCH(note_text)AGAINST('PICASO') FROM tb_name;
InnoDB引擎不支持全文检索,MyISAM可以;
三、性能优化
- explain执行计划用法
mysql> explain select * from event;
+—-+————-+——-+——+—————+——+———+——+——+——-+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+—-+————-+——-+——+—————+——+———+——+——+——-+
| 1 | SIMPLE | event | ALL | NULL | NULL | NULL | NULL | 13 | |
+—-+————-+——-+——+—————+——+———+——+——+——-+
1 row in set (0.00 sec)
id:select查询的序列号
select_type:select查询的类型,主要是区别普通查询和联合查询、子查询之类的复杂查询。
table:输出的行所引用的表。
type:联合查询所使用的类型。是较为重要的一个指标,结果值从好到坏依次是:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL,一般来说,得保证查询至少达到range级别,最好能达到ref。
possible_keys:指出MySQL能使用哪个索引在该表中找到行。如果是空的,没有相关的索引。
key:显示MySQL实际决定使用的键。如果没有索引被选择,键是NULL。
key_len:显示MySQL决定使用的键长度。如果键是NULL,长度就是NULL。文档提示特别注意这个值可以得出一个多重主键mysql实际使用了哪一部分。
ref:显示哪个字段或常数与key一起被使用。
rows:这个数表示mysql要遍历多少数据才能找到,在innodb上是不准确的。
Extra:
如果是Only index,这意味着信息只用索引树中的信息检索出的,这比扫描整个表要快。
如果是where used,就是使用上了where限制。
如果是impossible where 表示用不着where,一般就是没查出来啥。
如果此信息显示Using filesort或者Using temporary的话会很吃力,WHERE和ORDER BY的索引经常无法兼顾,如果按照WHERE来确定索引,那么在ORDER BY时,就必然会引起Using filesort,这就要看是先过滤再排序划算,还是先排序再过滤划算。
常见的一些名词解释。
Using filesort:MySQL需要额外的一次传递,以找出如何按排序顺序检索行。
Using index:从只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的列信息。
Using temporary:为了解决查询,MySQL需要创建一个临时表来容纳结果。
ref:对于每个来自于前面的表的行组合,所有有匹配索引值的行将从这张表中读取
ALL:完全没有索引的情况,性能非常地差劲。
index:与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。
SIMPLE:简单SELECT(不使用UNION或子查询)
表查询要尽量使用索引
索引失效的情况
like全匹配、<>和 != 会失效(主键索引除外)、or,但是没有把or中所有字段加上索引、where语句中对字段表达式或函数操作、使用Not In、使用 is null 或者 is not null、排序使用了索引,而select列未使用索引列,则该索引失效、组合索引未使用最左侧的索引经常增删改查的列不要建索引,因为修改数据的同时,索引也是要修改的。
尽量选择区分度高的列作为索引,大量重复数据的列不建议建索引
复合索引最左前缀匹配原则
减少索引长度:设置索引时可能的话应该指定一个前缀长度。例如,如果有一个CHAR(255)的 列,如果在前10 个或20 个字符内,多数值是惟一的,那么就不要对整个列进行索引
覆盖索引。对联合索引(col1,col2,col3),如果有如下的sql: select col1,col2,col3 from test where col1=1 and col2=2。那么MySQL可以直接通过遍历索引表取得数据,而无需回表。
避免频繁创建和删除临时表,以减少系统表资源的消耗。
优化案例
1.实际案例分析:拆分大的 DELETE 或INSERT 语句,批量提交SQL语句,因为这两个操作是会锁表的,表一锁住了,别的操作都进不来了
2.粉丝查询优化:sql简化,有时候业务处理放到代码层,能达到意想不到的效果
3.私信优化 :适当冗余数据、冗余字段,把数据量从大化小的典型案例,降低sql的复杂度
4.关注数据库状态:当你发现数据库cpu或者io有异常现象时候,用show processlist看看数据库在忙什么不是所有SQL语句都能通过SQL优化,业务上的调整带来意想不到的效果;
所有的性能优化都是空间换时间,通过冗余来提高性能,大体思路都是大化小,分而治之
索引利大于弊,多用,善用之
如果再卡,可能会从分库分表,读写分离这方面入手了。
四、索引
B-Tree索引
索引存储的值按索引列中的顺序排列。可以用B-Tree索引进行全关键字、关键字范围和关键字前缀查询。如果使用索引,必须保证按索引最左边前缀进行查询。由于B树中节点是顺序存储的,可以对查询结果进行order by。
BTREE索引,使用大于,小于,BETWEEN,不等于,LIKE等操作符的时候都可以用。对索引字段进行范围查询的时候,只有BTREE索引可以通过索引访问。HASH索引实际上是全表扫描的。Hash索引
MySQL中只有Memory存储引擎显示支持hash索引,是默认索引类型,它也支持B-Tree索引。
缺点:(1)Hash 索引仅仅能满足"=","IN"和"<=>"查询,不能使用范围查询。
由于 Hash 索引比较的是进行 Hash 运算之后的 Hash 值,所以它只能用于等值的过滤,不能用于基于范围的过滤,因为经过相应的 Hash 算法处理之后的 Hash 值的大小关系,并不能保证和Hash运算前完全一样。
(2)Hash 索引无法被用来避免数据的排序操作。
由于 Hash 索引中存放的是经过 Hash 计算之后的 Hash 值,而且Hash值的大小关系并不一定和 Hash 运算前的键值完全一样,所以数据库无法利用索引的数据来避免任何排序运算;
(3)Hash 索引不能利用部分索引键查询。
对于组合索引,Hash 索引在计算 Hash 值的时候是组合索引键合并后再一起计算 Hash 值,而不是单独计算 Hash 值,所以通过组合索引的前面一个或几个索引键进行查询的时候,Hash 索引也无法被利用。
(4)Hash 索引在任何时候都不能避免表扫描。
前面已经知道,Hash 索引是将索引键通过 Hash 运算之后,将 Hash运算结果的 Hash 值和所对应的行指针信息存放于一个 Hash 表中,由于不同索引键存在相同 Hash 值,所以即使取满足某个 Hash 键值的数据的记录条数,也无法从 Hash 索引中直接完成查询,还是要通过访问表中的实际数据进行相应的比较,并得到相应的结果。
(5)Hash 索引遇到大量Hash值相等的情况后性能并不一定就会比B-Tree索引高。
对于选择性比较低的索引键,如果创建 Hash 索引,那么将会存在大量记录指针信息存于同一个 Hash 值相关联。这样要定位某一条记录时就会非常麻烦,会浪费多次表数据的访问,而造成整体性能低下
如果多个值有相同的hash code,索引把它们的行指针用链表保存到同一个hash表项中。
因为索引自己仅仅存储很短的值,所以索引非常紧凑,hash值不取决于列的数据类型,
int列的索引和长字符串列的索引一样大。
HASH索引适合等式比较的操作,不能用来加速order by操作,也不能确定在两个值之间大约有多少行,会影响一些查询的执行效率。而且只能使用整个关键字来搜索一行。索引种类
普通索引:仅加速查询
唯一索引:加速查询 + 列值唯一(可以有null)
主键索引:加速查询 + 列值唯一(不可以有null)+ 表中只有一个
组合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并
全文索引:对文本的内容进行分词,进行搜索
五、存储引擎
(1)InnoDB存储引擎
InnoDB是MySQL默认的存储引擎,是事务型数据库的首选引擎,支持事务安全表(ACID),支持行锁定和外键,支持奔溃后自动回复,支持级联删除和更新。(2)MyISAM存储引擎
MyISAM基于ISAM存储引擎,并对其进行扩展。它是在Web、数据仓储和其他应用环境下最常使用的存储引擎之一。MyISAM支持表的压缩(压缩后的表是只读的,不可以进行修改等操作)和拥有较高的插入和查询速度,但不支持事务。(3)MEMORY存储引擎
MEMORY 是内存型的数据库引擎,它会将表中的数据存储到内存中,因为它是内存级的数据引擎,因此具备最快速的查询效率,但它的缺点是,重启数据库之后,所有数据都会丢失,因为这些数据是存放在内存中的。
六、主从复制的几种方式
-
- 基于 SQL 语句的复制(statement-based replication, SBR);
每一条会修改数据的sql语句会记录到binlog中。优点是并不需要记录每一条sql语句和每一行的数据变化,减少了binlog日志量,节约IO,提高性能。缺点是在某些情况下会导致master-slave中的数据不一致(如sleep()函数, last_insert_id(),以及user-defined functions(udf)等会出现问题)
优点:
历史悠久,技术成熟 binlog 文件较小
binlog 中包含了所有数据库更改信息,可以据此来审核数据库的安全等情况
binlog 可以用于实时的还原,而不仅仅用于复制
主从版本可以不一样,从服务器版本可以比主服务器版本高
缺点:
不是所有的 UPDATE 语句都能被复制,尤其是包含不确定操作的时候。
复制需要进行全表扫描(WHERE 语句中没有使用到索引)的 UPDATE 时,需要比 RBR 请求更多的行级锁
对于一些复杂的语句,在从服务器上的耗资源情况会更严重,而 RBR 模式下,只会对那个发生变化的记录产生影响 数据表必须几乎和主服务器保持一致才行,否则可能会导致复制出错
执行复杂语句如果出错的话,会消耗更多资源。
- 基于 SQL 语句的复制(statement-based replication, SBR);
-
- 基于行的复制(row-based replication, RBR);
优点:
任何情况都可以被复制,这对复制来说是最安全可靠的
和其他大多数数据库系统的复制技术一样
多数情况下,从服务器上的表如果有主键的话,复制就会快了很多
缺点:
binlog 大了很多
复杂的回滚时 binlog 中会包含大量的数据
主服务器上执行 UPDATE 语句时,所有发生变化的记录都会写到 binlog 中,而 SBR 只会写一次,这会导致频繁发生 binlog 的并发写问题
无法从 binlog 中看到都复制了写什么语句
- 基于行的复制(row-based replication, RBR);
3.混合模式复制(mixed-based replication, MBR);
基于 SQL 语句的方式最古老的方式,也是目前默认的复制方式,后来的两种是 MySQL 5 以后才出现的复制方式。主从复制工作原理剖析
1.Master 数据库只要发生变化,立马记录到Binary log 日志文件中
2.Slave数据库启动一个I/O thread连接Master数据库,请求Master变化的二进制日志
3.Slave I/O获取到的二进制日志,保存到自己的Relay log 日志文件中。
4.Slave 有一个 SQL thread定时检查Realy log是否变化,变化那么就更新数据