赞
踩
连接器(Connectors)
系统管理和控制工具(Management Serveices & Utilities)
连接池(Connection Pool) SQL Layer MySQL业务层
SQL接口(SQL Interface) 接收SQL DML DDL
解析器(Parser) select * from t1
词法分析 分词 ----- 》形成语法树
语法分析 分析 : 符合SQL的语法 SQL的语法 : SQL 92 limit MYSQL自己的语法 elect * from t1 语法错误 sytnx error … 形成正确语法树
查询优化器(Optimizer)
索引 只使用一个 使用最优
多表关联
where 从左到右 MySQL 找过滤力度最大的 先执行
查询缓存(Cache和Buffer) 把查询结果存起来 SQL — > hash后的值 唯一 则 表示有 Map
存储引擎(Pluggable Storage Engines)
MySQL是通过文件系统对数据和索引进行存储的。
MySQL从物理结构上可以分为日志文件和数据索引文件。
MySQL在Linux中的数据索引文件和日志文件都在/var/lib/mysql目录下。
日志文件采用顺序IO方式存储、数据文件采用随机IO方式存储。
默认是开启的,而且从5.5.7以后无法关闭错误日志,错误日志记录了运行过程中遇到的所有严重的错误 信息,以及 MySQL每次启动和关闭的详细信息。
记录数据变化 binlog记录了数据库所有的ddl语句和dml语句,但不包括select语句内容,语句以事件的形式保存,描 述了数据的变更顺序,binlog还包括了每个更新语句的执行时间信息。如果是DDL语句,则直接记录到 binlog日志,而DML语句,必须通过事务提交才能记录到binlog日志中。 生产中开启 数据备份、恢复、主从
啥都记录 耗性能 生产中不开启
SQL调优 定位慢的 select 默认是关闭的。 需要通过以下设置进行开启:
#开启慢查询日志
slow_query_log=ON
#慢查询的阈值
long_query_time=3
#日志记录文件如果没有给出file_name值, 默认为主机名,后缀为-slow.log。如果给出了文件名,但不
是绝对路径名,文件则写入数据目录。
slow_query_log_file=file_name
记录执行时间超过long_query_time秒的所有查询,便于收集查询时间比较长的SQL语句
看日志开启情况:
show variables like 'log_%';
SHOW VARIABLES LIKE '%datadir%
索引会占据磁盘空间 索
引虽然会提高查询效率,但是会降低更新表的效率**。比如每次对表进行增删改操作, MySQL不仅要保存数据,还有保存或者更新对应的索引文件。
CREATE INDEX index_name ON table(column(length)) ;
ALTER TABLE table_name ADD INDEX index_name (column(length)) ;
CREATE UNIQUE INDEX index_name ON table(column(length)) ;
alter table table_name add unique index index_name(column);
CREATE FULLTEXT INDEX index_name ON table(column(length)) ;
alter table table_name add fulltext index_name(column)
ALTER TABLE article ADD INDEX index_titme_time (title(50),time(10)) ;
DROP INDEX index_name ON table
SHOW INDEX FROM table_name \G
B树是为了磁盘或其它存储设备而设计的一种多叉(下面你会看到,相对于二叉,B树每个内结点有多个 分支,即多叉)平衡查找树。 多叉平衡
1、主键自动建立唯一索引
2、频繁作为查询条件的字段应该创建索引
3、多表关联查询中,关联字段应该创建索引 on l两边都要创建索引
4、查询中排序的字段,B+树有顺序
5、覆盖索引?好处是 不需要回表-》组合索引
6、统计或者分组字段,应该创建索引
1、表记录太少 索引是要有存储的开销
2、频繁更新 索引要维护
3、查询字段使用频率不高
explain出来的信息有10列,分别是
id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra
--用户表 create table tuser( id int primary key, loginname varchar(100), name varchar(100), age int, sex char(1), dep int, address varchar(100) ); --部门表 create table tdep( id int primary key, name varchar(100) ); --地址表 create table taddr( id int primary key, addr varchar(100) ); --创建普通索引 mysql> alter table tuser add index idx_dep(dep); --创建唯一索引 mysql> alter table tuser add unique index idx_loginname(loginname); --创建组合索引 mysql> alter table tuser add index idx_name_age_sex(name,age,sex); --创建全文索引 mysql> alter table taddr add fulltext ft_addr(addr);
查询类型,主要用于区别普通查询、联合查询(union、union all)、子查询等复杂查询。
表示不需要union操作或者不包含子查询的简单select查询。有连接查询时,外层的查询为simple,且 只有一个
一个需要union操作或者含有子查询的select,位于最外层的单位查询的select_type即为primary。且只 有一个
除了from字句中包含的子查询外,其他地方出现的子查询都可能是subquery
与dependent union类似,表示这个subquery的查询要受到外部表查询的影响
union连接的两个select查询,第一个查询是PRIMARY,除了第一个表外,第二个以后的表select_type 都是union
与union一样,出现在union 或union all语句中,但是这个查询要受到外部查询的影响
包含union的结果集,在union和union all语句中,因为它不需要参与查询,所以id字段为null
from字句中出现的子查询,也叫做派生表,其他数据库中可能叫做内联视图或嵌套select
依次从好到差:system,const,eq_ref,ref,fulltext,ref_or_null,unique_subquery,
index_subquery,range,index_merge,index,ALL
除了all之外,其他的type都可以使用到索引,除了index_merge之外,其他的type只可以用到一个索 引
优化器会选用最优索引 一个
最少要索引使用到range级别。
表中只有一行数据或者是空表。
使用唯一索引或者主键,返回记录一定是1行记录的等值where条件时,通常type是const。其他数据库 也叫做唯一索引扫描
关键字:连接字段主键或者唯一性索引。 此类型通常出现在多表的 join 查询, 表示对于前表的每一个结果, 都只能匹配到后表的一行结果. 并且查 询的比较操作通常是 ‘=’, 查询效率较高.
针对非唯一性索引,使用等值(=)查询非主键。或者是使用了最左前缀规则索引的查询。
全文索引检索,要注意,全文索引的优先级很高,若全文索引和普通索引同时存在时,mysql不管代 价,优先选择使用全文索引
与ref方法类似,只是增加了null值的比较。实际用的不多。
用于where中的in形式子查询,子查询返回不重复值唯一值
用于in形式子查询使用到了辅助索引或者in常数列表,子查询可能返回重复值,可以使用索引将子查询 去重。
索引范围扫描,常见于使用>,<,is null,between ,in ,like等运算符的查询中。
表示查询使用了两个以上的索引,最后取交集或者并集,常见and ,or的条件使用了不同的索引,官方排序这个在ref_or_null之后,但是实际上由于要读取所个索引,性能可能大部分时间都不如range
关键字:条件是出现在索引树中的节点的。可能没有完全匹配索引。
索引全表扫描,把索引从头到尾扫一遍,常见于使用索引列就可以处理不需要读取数据文件的查询、可 以使用索引排序或者分组的查询。
这个就是全表扫描数据文件,然后再在server层进行过滤返回符合要求的记录
此次查询中可能选用的索引,一个或多个
查询真正使用到的索引,select_type为index_merge时,这里可能出现两个以上的索引,其他的 select_type这里只会出现一个。
这里是执行计划中估算的扫描行数,不是精确值(InnoDB不是精确的值,MyISAM是精确的值,主要原 因是InnoDB里面使用了MVCC并发机制)
这个列包含不适合在其他列中显示单十分重要的额外的信息,这个列可以显示的信息非常多,有几十 种,常用的有
在select部分使用了distinct关键字
不带from字句的查询或者From dual查询
使用not in()形式子查询或not exists运算符的连接查询,这种叫做反连接 即,一般连接查询是先查询内表,再查询外表,反连接就是先查询外表,再查询内表。
表示存储引擎返回的记录并不是所有的都满足查询条件,需要在server层进行过滤。
查询条件中分为限制条件和检查条件,5.6之前,存储引擎只能根据限制条件扫描数据并返回,然 后server层根据检查条件进行过滤再返回真正符合查询的数据。5.6.x之后支持ICP特性,可以把检 查条件也下推到存储引擎层,不符合检查条件和限制条件的数据,直接不读取,这样就大大减少了 存储引擎扫描的记录数量。extra列显示using index condition
条件与索引一一对应
如果索引了多个列,要遵守最佳左前缀法则。指的是查询从索引的最左前列开始 并且不跳过索引中的 列。
不要进行这些操作:计算、函数、自动/手动类型转换,不然会导致索引失效而转向全表扫描
不能继续使用索引中范围条件(bettween、<、>、in等)右边的列
尽量使用覆盖索引(只查询索引的列),也就是索引列和查询列一致,减少select *
索引字段上使用(!= 或者 < >)判断时,会导致索引失效而转向全表扫描
主键字段上不可以使用 null
索引字段上使用 is null 判断时,可使用索引
索引字段使用like以通配符开头(‘%字符串’)时,会导致索引失效而转向全表扫描
索引字段是字符串,但查询时不加单引号,会导致索引失效而转向全表扫描
索引字段使用 or 时,会导致索引失效而转向全表扫描
MySQL 实现的表级锁定的争用状态变量:
show status like 'table%';
- table_locks_immediate:产生表级锁定的次数;
-table_locks_waited:出现表级锁定争用而发生等待的次数;
开启事务 begin
或者start transcation
。配套的提交语句是commit
,回滚语句为rollback
。
MDL (metaDataLock) 元数据:表结构 在 MySQL 5.5 版本中引入了 MDL,当对一个表做增删改查操作的时候,加 MDL 读锁;当要对表做结 构变更操作的时候,加 MDL 写锁。
InnoDB存储引擎实现
InnoDB的行级锁,按照锁定范围来说,分为三种:
共享读锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。
SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE -- 共享读锁 手动添加
select * from table -- 无锁
排他写锁(X):允许获得排他写锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁(不是 读)和排他写锁。
1、自动加 DML
对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及数据集加排他锁(X);
2、手动加
SELECT * FROM table_name WHERE ... FOR UPDATE
InnoDB也实现了表级锁,也就是意向锁,意向锁是mysql内部使用的,不需要用户干预。
意向锁的主要作用是为了【全表更新数据】时的性能提升。否则在全表更新数据时,需要先检索该 表是否某些记录上面有行锁。
锁操作分为两个阶段:加锁阶段与解锁阶段, 加锁阶段与解锁阶段不相交。 加锁阶段:只加锁,不放锁。 解锁阶段:只放锁,不加锁。
InnoDB行锁是通过给索引上的索引项加锁来实现的,因此InnoDB这种行锁实现特点意味着:只有通过 索引条件检索的数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!
查看行锁状态 show STATUS like 'innodb_row_lock%';
Innodb_row_lock_current_waits:当前正在等待锁定的数量;
Innodb_row_lock_time:从系统启动到现在锁定总时间长度;
Innodb_row_lock_time_avg:每次等待所花平均时间;
Innodb_row_lock_time_max:从系统启动到现在等待最常的一次所花的时间;
Innodb_row_lock_waits:系统启动后到现在总共等待的次数;
(1)对于键值在条件范围内但并不存在的记录(在相等条件下请求给一个不存在的记录也会加锁),叫做“间隙(GAP)”,InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁(Next-Key锁)。
(2)查询使用的范围条件不是相等条件,InnoDB会给符合条件的已有数据记录的索引项加锁;
两个 session 互相等等待对方的资源释放之后,才能释放自己的资源,造成了死锁
开启:
slow_query_log=ON
long_query_time=3
slow_query_log_file=/var/lib/mysql/slow-log.log
开启慢查询功能
常用参数说明:
percona-toolkit是一组高级命令行工具的集合,可以查看当前服务的摘要信息,磁盘检测,分析慢查询 日志,查找重复索引,实现表同步等等。
Query Profiler是MySQL自带的一种query诊断分析工具,通过它可以分析出一条SQL语句的硬件性能 瓶颈在什么地方。比如CPU,IO等,以及该SQL执行所耗费的时间等。不过该工具只有在MySQL 5.0.37 以及以上版本中才有实现。默认的情况下,MYSQL的该功能没有打开,需要自己手动启动。
select @@profiling;
show variables like ‘%profil%’;
set profiling=1; --1是开启、0是关闭
buffer pool 默认128M
扩大buffer pool 理论上内存的3/4或4/5
怎样确定 innodb_buffer_pool_size 足够大。数据是从内存读取而不是硬盘?
先执行一次
SSD
索引优化
where 字段 、组合索引 (最左前缀) 、 索引下推 (非选择行 不加锁) 、索引覆盖(不回表)
on 两边 排序 分组统计
不要用 *
LIMIT优化
官方网站:http://shardingsphere.apache.org/index_zh.html
数据分片分为垂直分片和水平分片
水平拆分的数据库(表)的相同逻辑和数据结构的总称
在分片的数据库中真实存在的物理表
数据分片的最小单元,由数据名称和数据表组成
指分片规则一致的主表和子表,例如order表和order_item表,均按照order_id分片,则此两张表互为绑定表关系,绑定表之间的多表关联查询不会出现笛卡尔积关联,关联查询效率大大提升。
指所有的分片数据源中都存在的表,表结构和表中的数据在每个数据库中完全一致。适用于数据量不大且需要与海量数据的表进行关联查询的场景,如字典表
包含分片键和分片算法。分片键是用于分片的数据库字段,是将数据库(表)水平拆分的关键字段。
精确分片算法、范围分片算法、复合分片算法、Hint分片算法
用于处理使用单一键作为分片键的=与IN进行分片的场景,需要配合StandardShardingStrategy使用
用于处理使用单一键作为分片键的BWTWEEN AND进行分片的场景,需要配合StandardShardingStrategy使用
用于处理使用多键作为分片键的进行分片的场景,包含多个分片键的逻辑较复杂,需要应用开发者自行处理其中的复杂度,需要配合ComplexShardingStrategy使用
先范围再取模
id1-500
奇数
偶数
500-1000
奇数
偶数
用于处理使用Hint行分片的场景,需要配合HintShardingState使用
标准分片策略、复合分片策略、行表达式分片策略、Hint分片策略
对应StandardShardingStrategy。提供对SQL语句中的=, >, <, >=, <=, IN和BETWEEN AND的分片操作支持。StandardShardingStrategy只支持单分片键,提供PreciseShardingAlgorithm和RangeShardingAlgorithm两个分片算法。PreciseShardingAlgorithm是必选的,用于处理=和IN的分片。RangeShardingAlgorithm是可选的,用于处理BETWEEN AND, >, <, >=, <=分片,如果不配置RangeShardingAlgorithm,SQL中的BETWEEN AND将按照全库路由处理。
对应ComplexShardingStrategy。复合分片策略。提供对SQL语句中的=, >, <, >=, <=, IN和BETWEEN AND的分片操作支持。ComplexShardingStrategy支持多分片键,由于多分片键之间的关系复杂,因此并未进行过多的封装,而是直接将分片键值组合以及分片操作符透传至分片算法,完全由应用开发者实现,提供最大的灵活度。
对应InlineShardingStrategy。使用Groovy的表达式,提供对SQL语句中的=和IN的分片操作支持,只支持单分片键。对于简单的分片算法,可以通过简单的配置使用,从而避免繁琐的Java代码开发,如: t_user_$->{u_id % 8}
表示t_user表根据u_id模8,而分成8张表,表名称为t_user_0
到t_user_7
。
对应HintShardingStrategy。通过Hint指定分片值而非从SQL中提取分片值的方式进行分片的策略。
对应NoneShardingStrategy。不分片的策略。
分片规则配置的总入口。包含数据源配置、表配置、绑定表配置以及读写分离配置等。
真实数据源列表。
逻辑表名称、数据节点与分表规则的配置。
用于配置逻辑表与真实表的映射关系。可分为均匀分布和自定义分布两种形式。
对于分片策略存有数据源分片策略和表分片策略两种维度。
通过在客户端生成自增主键替换以数据库原生自增主键的方式,做到分布式主键无重复。
按照全库路由处理。
对应ComplexShardingStrategy。复合分片策略。提供对SQL语句中的=, >, <, >=, <=, IN和BETWEEN AND的分片操作支持。ComplexShardingStrategy支持多分片键,由于多分片键之间的关系复杂,因此并未进行过多的封装,而是直接将分片键值组合以及分片操作符透传至分片算法,完全由应用开发者实现,提供最大的灵活度。
对应InlineShardingStrategy。使用Groovy的表达式,提供对SQL语句中的=和IN的分片操作支持,只支持单分片键。对于简单的分片算法,可以通过简单的配置使用,从而避免繁琐的Java代码开发,如: t_user_$->{u_id % 8}
表示t_user表根据u_id模8,而分成8张表,表名称为t_user_0
到t_user_7
。
对应HintShardingStrategy。通过Hint指定分片值而非从SQL中提取分片值的方式进行分片的策略。
对应NoneShardingStrategy。不分片的策略。
分片规则配置的总入口。包含数据源配置、表配置、绑定表配置以及读写分离配置等。
真实数据源列表。
逻辑表名称、数据节点与分表规则的配置。
用于配置逻辑表与真实表的映射关系。可分为均匀分布和自定义分布两种形式。
对于分片策略存有数据源分片策略和表分片策略两种维度。
通过在客户端生成自增主键替换以数据库原生自增主键的方式,做到分布式主键无重复。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。