MYSQL
一、为什么使用数据库?
数据保存位置 | 内存 | 文件 | 数据库 |
---|---|---|---|
优点 | 存取速度快 | 数据永久保存 | 数据永久保存,使用SQL管理数据方便 |
缺点 | 不能永久保存 | 存取速度慢,频繁io操作 | --- |
二、什么是SQL?
SQL(Structured Query Language)结构化查询语言:是一种数据库管理语言,用于查询,更新,删除和管理关系型数据库。
三、什么是MYSQL?
-
MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司。
-
MySQL是一种关联数据库管理系统,将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。
-
Mysql是开源的,所以你不需要支付额外的费用。
-
Mysql是可以定制的,采用了GPL协议,你可以修改源码来开发自己的Mysql系统。
-
Mysql支持大型的数据库。可以处理拥有上千万条记录的大型数据库。
-
MySQL使用标准的SQL数据语言形式。
-
Mysql可以允许于多个系统上,并且支持多种语言。这些编程语言包括C、C++、Python、Java、Perl、PHP、Eiffel、Ruby和Tcl等。
-
MySQL支持大型数据库,支持5000万条记录的数据仓库,32位系统表文件最大可支持4GB,64位系统支持最大的表文件为8TB。
四、mysql存储引擎
1、InnoDB存储引擎 InnoDB是MySQL的默认事务型引擎,它被设计用来处理大量的短期(short-lived)事务。除非有非常特别的原因需要使用其他的存储引擎,否则应该优先考虑InnoDB引擎。行级锁,适合高并发情况
2、MyISAM存储引擎 MyISAM提供了大量的特性,包括全文索引、压缩、空间函数(GIS)等,但MyISAM不支持事务和行级锁(myisam改表时会将整个表全锁住),有一个毫无疑问的缺陷就是崩溃后无法安全恢复。
3、Archive引擎 Archive存储引擎只支持INSERT和SELECT操作,在MySQL5.1之前不支持索引。 Archive表适合日志和数据采集类应用。适合低访问量大数据等情况。 根据英文的测试结论来看,Archive表比MyISAM表要小大约75%,比支持事务处理的InnoDB表小大约83%。
4、Blackhole引擎 Blackhole引擎没有实现任何存储机制,它会丢弃所有插入的数据,不做任何保存。但服务器会记录Blackhole表的日志,所以可以用于复制数据到备库,或者简单地记录到日志。但这种应用方式会碰到很多问题,因此并不推荐。
5、CSV引擎 CSV引擎可以将普通的CSV文件作为MySQL的表来处理,但不支持索引。 CSV引擎可以作为一种数据交换的机制,非常有用。 CSV存储的数据直接可以在操作系统里,用文本编辑器,或者excel读取。
6、Memory引擎 如果需要快速地访问数据,并且这些数据不会被修改,重启以后丢失也没有关系,那么使用Memory表是非常有用。Memory表至少比MyISAM表要快一个数量级。(使用专业的内存数据库更快,如redis)
7、Federated引擎 Federated引擎是访问其他MySQL服务器的一个代理,尽管该引擎看起来提供了一种很好的跨服务器的灵活性,但也经常带来问题,因此默认是禁用的。
五、Innodb与myisam存储引擎比较
对比项 | MyISAM | InnoDB |
---|---|---|
主外键 | 不支持 | 支持 |
事务 | 不支持 | 支持 |
行表锁 | 表锁,即使操作一条记录,也会锁住整个表,不适合高并发操作 | 行锁,仅仅锁住表中的一行记录,不会对其他行有影响,适合高并发 |
缓存 | 只缓存索引,不缓存真实数据 | 不仅缓存索引还要缓存真实数据,对内存要求较高,内存大小对性能有决定性影响 |
表空间 | 小 | 大 |
关注点 | 性能 | 事务 |
是否默认安装 | Y | Y |
用户表默认使用 | N | Y |
自带系统表使用 | Y | N |
索引 | B+树:数据只存放在叶子节点 | B树(B-树):每个节点都存放数据 |
文件存放 | frm文件存放表结构 myd文件存放表数据 myi文件存放表索引 | frm文件存放表结构 ibd文件存放表数据及表索引 |
六、索引
1 索引是什么?
MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。 可以得到索引的本质:索引是数据结构。
可以简单理解为“排好序的快速查找数据结构”
2 优缺点
优点:
-
提高数据检索的效率,降低数据库的IO成本
-
通过索引列对数据进行排序,降低数据排序的成本,降低了CPU的消耗
缺点:
-
索引也要占用空间
-
虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。 因为更新表时,不仅要保存数据,还要保存一下索引文件每次更新添加了索引列的字段, 都会调整因为更新所带来的键值变化后的索引信息
3 mysql 中的索引结构
(1) B树索引
(2) B+树索引
B树与B+树的区别
1)B树的关键字和记录是放在一起的,叶子节点可以看作外部节点,不包含任何信息;
B+树叶子节点中只有关键字和指向下一个节点的索引,记录只放在叶子节点中。
2)B树中,越靠近根节点的记录查找时间越快,只要找到关键字即可确定记录的存在;
B+树中每个记录的查找时间基本是一样的,都需要从根节点走到叶子节点,而且在叶子节点中还要再比较关键字。
结论:在内存有限的情况下,B+树 永远比 B树好。在无限内存则后者方便。
思考:为什么说B+树比B-树更适合实际应用中操作系统的文件索引和数据库索引?
1) B+树的磁盘读写代价更低
B+树的内部结点并没有指向关键字具体信息的指针。因此其内部结点相对B 树更小。如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说IO读写次数也就降低了。
2) B+树的查询效率更加稳定
由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。
(3) Hash索引
Hash索引只有Memory, NDB两种引擎支持,Memory引擎默认支持Hash索引,如果多个hash值相同,出现哈希碰撞,那么索引以链表方式存储。 NoSql采用此中索引结构。
(4) 聚簇索引与非聚簇索引
聚簇索引并不是一种单独的索引类型,而是一种数据存储方式。 术语‘聚簇’表示数据行和相邻的键值进错的存储在一起。 如下图,左侧的索引就是聚簇索引,因为数据行在磁盘的排列和索引排序保持一致。
聚簇索引的好处: 按照聚簇索引排列顺序,查询显示一定范围数据的时候,由于数据都是紧密相连,数据库不用从多个数据块中提取数据,所以节省了大量的io操作。 聚簇索引的限制: 对于mysql数据库目前只有innodb数据引擎支持聚簇索引,而Myisam并不支持聚簇索引。 由于数据物理存储排序方式只能有一种,所以每个Mysql的表只能有一个聚簇索引。一般情况下就是该表的主键。 为了充分利用聚簇索引的聚簇的特性,所以innodb表的主键列尽量选用有序的顺序id,而不建议用无序的id,比如uuid这种。
(5) 全文索引
全文索引(也称全文检索)是目前搜索引擎使用的一种关键技术。它能够利用【分词技术】等多种算法智能分析出文本文字中关键词的频率和重要性,然后按照一定的算法规则智能地筛选出我们想要的搜索结果。
CREATE TABLE `article` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `title` varchar(200) DEFAULT NULL, `content` text, PRIMARY KEY (`id`), FULLTEXT KEY `title` (`title`,`content`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; #不同于like方式的的查询: SELECT * FROM article WHERE content LIKE ‘%查询字符串%’; #全文索引用match+against方式查询: SELECT * FROM article WHERE MATCH(title,content) AGAINST (‘查询字符串’); #明显的提高查询效率。 /*限制: mysql5.6.4以前只有Myisam支持,5.6.4版本以后innodb才支持,但是官方版本不支持中文分词,需要第三方分词插件。 5.7以后官方支持中文分词。 随着大数据时代的到来,关系型数据库应对全文索引的需求已力不从心,逐渐被 solr,elasticSearch等专门的搜索引擎所替代。*/
(6) R-Tree索引
R-Tree在mysql很少使用,仅支持geometry数据类型,支持该类型的存储引擎只有myisam、bdb、innodb、ndb、archive几种。
相对于b-tree,r-tree的优势在于范围查找。
4 创建索引的情况
(1)哪些情况需要创建索引
-
主键自动建立唯一索引
-
频繁作为查询条件的字段应该创建索引(where 后面的语句)
-
查询中与其它表关联的字段,外键关系建立索引
-
单键/组合索引的选择问题,(在高并发下倾向创建组合索引)
-
查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度
-
查询中统计或者分组字段
(2)哪些情况不要创建索引
-
表记录太少
-
经常增删改的表
-
Where条件里用不到的字段不创建索引
-
数据重复且分布平均的表字段,因此应该只为最经常查询和最经常排序的数据列建立索引。 注意,如果某个数据列包含许多重复的内容,为它建立索引就没有太大的实际效果。
七、mysql 执行计划
1 mysql常见瓶颈
-
CPU:SQL中对大量数据进行比较、关联、排序、分组(最大的压力在于 比较)
-
IO:实例内存满足不了缓存数据或排序等需要,导致产生大量 物理 IO。
查询执行效率低,扫描过多数据行。
-
锁:不适宜的锁的设置,导致线程阻塞,性能下降。
死锁,线程之间交叉调用资源,导致死锁,程序卡住。
2 执行计划 explain
执行计划包含的信息
(1) 表的读取顺序——id
在所有组中,id值越大,优先级越高,越先执行
id如果相同,可以认为是一组,从上往下顺序执行
(2)查询的类型——select_type
查询的类型,主要是用于区别普通查询、联合查询、子查询等的复杂查询
-
SIMPLE:简单的 select 查询,查询中不包含子查询或者UNION
-
PRIMARY:查询中若包含任何复杂的子部分,最外层查询则被标记为Primary
-
DERIVED:在FROM列表中包含的子查询被标记为DERIVED(衍生),MySQL会递归执行这些子查询, 把结果放在临时表里
-
SUBQUERY:在SELECT或WHERE列表中包含了子查询
-
DEPENDENT SUBQUERY:在SELECT或WHERE列表中包含了子查询,子查询基于外层
-
UNCACHEABLE SUBQUREY:无法被缓存的子查询
-
UNION:若第二个SELECT出现在UNION之后,则被标记为UNION;若UNION包含在FROM子句的子查询中,外层SELECT将被标记为:DERIVED
-
UNION RESULT:从UNION表获取结果的SELECT
(3)执行哪张表——table
显示这一行的数据是关于哪张表的
(4)数据读取操作的操作类型——type
type显示的是访问类型,是较为重要的一个指标,结果值从最好到最坏依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range(尽量保证) > index > ALL
显示查询使用了何种类型,从最好到最差依次是:
system>const>eq_ref>ref>range>index>ALL
备注:一般来说,得保证查询至少达到range级别,最好能达到ref。
-
system:表只有一行记录(等于系统表),这是const类型的特列,平时不会出现,这个也可以忽略不计
-
const:表示通过索引一次就找到了,const用于比较primary key或者unique索引。因为只匹配一行数据,所以很快如将主键置于where列表中,MySQL就能将该查询转换为一个常量
-
eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描
-
ref:非唯一性索引扫描,返回匹配某个单独值的所有行.本质上也是一种索引访问,它返回所有匹配某个单独值的行,然而,它可能会找到多个符合条件的行,所以他应该属于查找和扫描的混合体
-
range:只检索给定范围的行,使用一个索引来选择行。key 列显示使用了哪个索引,一般就是在你的where语句中出现了between、<、>、in等的查询,这种范围扫描索引扫描比全表扫描要好,因为它只需要开始于索引的某一点,而结束语另一点,不用扫描全部索引。
-
index:Full Index Scan,index与ALL区别为index类型只遍历索引树。这通常比ALL快,因为索引文件通常比数据文件小。(也就是说虽然all和Index都是读全表,但index是从索引中读取的,而all是从硬盘中读的)
-
all:Full Table Scan,将遍历全表以找到匹配的行
-
index_merge:在查询过程中需要多个索引组合使用,通常出现在有 or 的关键字的sql中
-
ref_or_null:对于某个字段既需要关联条件,也需要null值得情况下。查询优化器会选择用ref_or_null连接查询。
-
index_subquery:利用索引来关联子查询,不再全表扫描。
-
unique_subquery :该联接类型类似于index_subquery。 子查询中的唯一索引
(5)哪些索引可以使用——possible_keys
显示可能应用在这张表中的索引,一个或多个。
查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询实际使用
(6)哪些索引被实际使用——key
实际使用的索引。如果为NULL,则没有使用索引
(7)索引中使用的字节数——key_len
表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度。
key_len字段能够帮你检查是否充分的利用上了索引
(8)表之间的引用——ref
显示索引的哪一列被使用了,如果可能的话,是一个常数。哪些列或常量被用于查找索引列上的值
(9)每张表有多少行被优化器查询——rows
rows列显示MySQL认为它执行查询时必须检查的行数。
(10)额外的重要信息——Extra
-
Using filesort:说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取,MySQL中无法利用索引完成的排序操作称为“文件排序”
-
Using temporary :使了用临时表保存中间结果,MySQL在对查询结果排序时使用临时表。常见于排序 order by 和分组查询 group by。
-
USING index:表示相应的select操作中使用了覆盖索引(Covering Index),避免访问了表的数据行,效率不错! 如果同时出现using where,表明索引被用来执行索引键值的查找; 如果没有同时出现using where,表明索引只是用来读取数据而非利用索引执行查找。
-
Using where:表明使用了where过滤
-
using join buffer:使用了连接缓存
-
impossible where:where子句的值总是false,不能用来获取任何元组
-
select tables optimized away:在没有GROUPBY子句的情况下,基于索引优化MIN/MAX操作或者,对于MyISAM存储引擎优化COUNT(*)操作,不必等到执行阶段再进行计算,查询执行计划生成的阶段即完成优化。
八、mysql 主从复制原理
MySQL复制过程分成三步: 1 master将改变记录到二进制日志(binary log)。这些记录过程叫做二进制日志事件,binary log events; 2 slave将master的binary log events拷贝到它的中继日志(relay log); 3 slave重做中继日志中的事件,将改变应用到自己的数据库中。 MySQL复制是异步的且串行化的