重点归纳-数据库

MySQL-索引

B+树索引的优点:
1、索引按照顺序存储数据,可以用来做ORDER BY和GROUP BY操作
2、索引中存储了实际的索引列值,所以某些査询只使用索引就能够完成全部査询(非一级索引的叶子节点存储主键)
3、索引大大减少了服务器需要扫描的数据量
4、索引可以帮助服务器避免排序和临时表
5、索引可以将随机I/O变为顺序I/O
B+树索引的缺点:
1、如果不是按照索引的最左列开始査找,则无法使用索引
2、不能跳过索引中的列(只能使用跳过前的列)
3、如果查询中有某个列的范围査询,则其右边所有列都无法使用索引优化査找(但是可以作为值返回);如果范围査询列值的数量有限,那么可以使用多个等于条件来代替范围条件
索引策略
1、独立的列:索引列不能是表达式的一部分,也不能是函数的参数,因此要始终将索引列单独放在比较符号的一侧
2、前缀索引和索引选择性:前缀越长,选择性越好
3、聚合(多列)索引:
当出现服务器对多个索引做相交操作时(通常有多个AND条件)或对多个索引做联合操作时(通常有多个OR条件),通常意味着需要一个包含所有相关列的多列索引,而不是多个独立的单列索引(需要合并)
多列索引中索引的顺序(需要兼顾排序和分组):当不需要考虑排序和分组时,将选择性最高的列放在前面通常是很好的
4、聚簇索引:当表有聚簇索引时,它的数据行实际上存放在索引的叶子页中,因为无法同时把数据行存放在两个不同的地方,所以一个表只能有一个聚簇索引(覆盖索引可以模拟多个聚簇索引的情况)
5、二级索引:访问需要两次索引査找,而不是一次,因为二级索引叶子节点保存的不是指向行的物理位置的指针,而是行的主键值,这意味着通过二级索引查找行,存储引擎需要找到二级索引的叶子节点获得对应的主键值,然后根据这个值去聚簇索引中査找到对应的行,这里做了重复的工作:两次B+树査找而不是一次(回表查询)
6、普通索引和唯一索引:普通索引在查找到一条记录后会继续查找,而唯一索引会终止查找
使用索引排序
1、只有当索引的列顺序和ORDER BY子句的顺序完全一致,并且所有列的排序方向(倒序或正序)都一样时,MySQL才能够使用索引来对结果做排序
2、如果査询需要关联多张表,则只有当ORDER BY子句引用的字段全部为第一个表时,才能使用索引做排序
3、ORDER BY子句和查找型查询的限制是一样的:需要满足索引的最左前缀的要求;否则MySQL都需要执行排序操作,而无法利用索引排序
有一种情况下ORDER BY子句可以不满足索引的最左前缀的要求,就是前导列为常量的时候;即如果WHERE子句或者JOIN子句中对这些列指定了常量,就可以“弥补”索引的不足

B树与B+树的区别

1、B树可能在非叶子节点命中返回(非叶子节点指针也指向数据,叶子节点不会包含非叶子节点的数据);B+不可能在非叶子结点命中
2、B+树叶子节点存放所有数据;B+树叶子节点之间又是一个链表(适合范围查询)

MySQL-事务

事务的特性
1、原子性:一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚
2、一致性:数据库总是从一个一致性的状态转换到另外一个一致性的状态
3、隔离性:通常来说(涉及到隔离级别),一个事务所做的修改在最终提交以前,对其他事务是不可见的
4、持久性:通常来说(涉及到持久级别),一旦事务提交,则其所做的修改就会永久保存到数据库中,此时即使系统崩溃,修改的数据也不会丢失
事务的隔离级别
1、读未提交:一个事务可以读取到其他事务未提交的数据(脏读)
2、读已提交(不可重复读):一个事务只能读取到其他事务此刻已提交的数据
3、可重复读:一个事务只能读取到其他事务在该事务开启时已提交的数据(快照读),但是无法避免幻读(单指插入,两次读取的结果不一致)
可重复读是MySQL的默认事务隔离级别,InnoDB通过MVCC(多版本并发控制)和next-key lock解决了幻读
4、串行读:强制事务串行执行,解决了幻读问题,在读取的每一行数据上都加锁,所以可能导致大量的超时和锁争用的问题
幻读:
1、幻读指的是一个事务在前后两次查询同一个范围的时候,后一次查询看到了前一次查询没有看到的行(单指插入);在可重复读隔离级别下,普通的查询是快照读,是不会看到别的事务插入的数据的(MVCC),幻读在“当前读”下仍会出现(加锁读时,只锁当前满足条件的行)
2、通过加间隙锁解决当前读导致的幻读,跟间隙锁存在冲突关系的,是跟 “往这个间隙中插入一个记录 ”这个操作,间隙锁之间都不存在冲突关系;间隙锁和行锁合称next-key lock,每个next-key lock是前开后闭区间
3、间隙锁是在可重复读隔离级别下才会生效的
4、一个并发问题:任意锁住一行,如果这一行不存在的话就插入,如果存在这一行就更新它的数据;因为锁的是间隙锁,并发时会锁竞争,发生死锁

MVCC-多版本并发控制(可重复读下)

查询(同时满足下面条件的,才作为结果返回):
a、査找版本早于当前事务版本的数据行(也就是行的系统版本号小于或等于事务的系统版本号),这样可以确保事务读取的行,要么是在事务开始前已经存在的,要么是事务自身插入或者修改过的
b、行的删除版本要么未定义,要么大于当前事务版本号,这可以确保事务读取到的行,在事务开始之前未被删除
插入:为新插入的每一行保存当前事务版本号作为行版本号
删除:为删除的每一行保存当前事务版本号作为行删除标识
修改:插入一行新记录,保存当前事务版本号作为行版本号,同时保存当前事务版本号到原来的行作为行删除标识
优点:保存这两个额外系统版本号,使大多数读操作都可以不用加锁,这样设计使得读数据操作很简单,性能很好,并且也能保证只会读取到符合标准的行
缺点:每行记录都需要额外的存储空间,需要做更多的行检査工作,以及一些额外的维护工作
MySQL没有完全解决幻读问题
如:事务a先查询(MVCC),事务b插入(next-key),事务a更新(next-key,会加版本号),事务a查询(MVCC),两次查询的结果不同
意向锁(表级锁):意向锁是由数据库自己维护的,一般来说,给一行数据加上共享锁之前,数据库会自动在这张表上面加一个意向共享锁(IS锁);给一行数据加上排他锁之前,数据库会自动在这张表上面加一个意向排他锁(IX锁)
意向锁可以认为是共享锁和互斥锁在数据表上的标识,通过意向锁可以快速判断表中是否有记录被上锁,从而避免通过遍历的方式来查看表中有没有记录被上锁,提升加锁效率
如要加表级别的互斥锁,这时候数据表里面如果存在行级别的互斥锁或者共享锁的,加锁就会失败,此时直接根据意向锁就能知道这张表是否有行级别的X锁或者S锁

MySQL-查询性能优化

从下面几点进行优化:
1、减少扫描行数(索引)
2、减少返回的行数或列数(limit或避免*)
如:
1、证件号码、证件名称、证件类型(聚合索引,冗余索引,顺序问题,减少回表)
2、select a.id,a.name from user a inner join (select b.id from user order by a.userId limit 1000,10) b on a.id = b.id
(原始的写法:select a.id,a.name from user a order by a.userId limit 1000,10)
(使用一级索引,减少回表)
join(小表驱动大表,大表用索引)
1、在可以使用被驱动表的索引(join字段)情况下,使用join语句,性能比强行拆成多个单表执行SQL语句的性能要好;如果使用join语句的话,需要让小表(根据条件查询出来少的表)做驱动表
2、在判断要不要使用join语句时,就是看explain结果里面,Extra字段里面有没有出现“Block Nested Loop”字样(出现则不用join)
3、如果用left join的话,左边的表一定是驱动表吗?不是
4、如果两个表的join包含多个条件的等值匹配,是都要写到on里面呢,还是只把一个条件写到on里面,其他条件写到where部分?写到on里面
5、在MySQL里,NULL跟任何值执行等值判断和不等值判断的结果,都是NULL;select NULL =NULL 的结果,也是返回 NULL

MySQL-执行流程

MySQL执行一个査询的过程:
1、客户端发送一条査询给服务器
2、服务器先检査査询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果,否则进入下一阶段
3、服务器端进行SQL解析、预处理,再由优化器生成对应的执行计划
4、MySQL根据优化器生成的执行计划,调用存储引擎的API来执行査询
5、将结果返回给客户端
更新:先找到要更新的数据,从磁盘读入内存;在执行器中执行语句,调用引擎先把记录写到redo log(覆盖写,磁盘中,物理日志)里面(原先的记录会写到undo log中,用于回滚),并更新内存,此时还未提交事务,在适当的时候,再将记录更新到磁盘;执行器写到binlog(不覆盖写,磁盘中,逻辑日志(语句));引擎将redo log改成提交状态,更新完成,即两阶段提交

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容