mysql简介

索引

索引是一种数据结构,是SQL编排数据的内部方法。

索引的优劣

  • 优势
    1)提高检索效率,降低IO成本
    2)通过索引列对数据进行排序,降低数据排序CPU消耗
  • 劣势
    1)索引也要占用空间
    2)提高查询速度的同时降低的更新表的速度

索引的分类

1)单列索引:一个索引值包含单个列,一个表可以有多个单列索引
2)唯一索引:索引列的值必须唯一,但允许有空值
3)复合索引:一个索引包含多个列

索引设计原则

1)对查询频次高且数据量大的表建立索引
2)索引字段的选择应从where子句的条件中提取
3)使用唯一索引,区分度高,效率高
4)使用短索引提升索引访问的I/O效率
5)针对复合索引,尽量利用最左前缀
6)尽量使用覆盖索引,避免使用select *
7)or前的条件有索引,or之后的条件没有索引,那么会导致索引失效
8)like模糊匹配%在前面索引失效
9)若mysql底层判断全表扫描比索引更快时,则索引失效
10)in走索引,而not in索引失效

索引的使用

1)全值匹配
2)最左前缀法则:查询从索引的最左前列开始,并且不跳过索引中的列
3)范围查询之后的索引失效
4)索引列上进行计算操作索引失效
5)字符串不加单引号索引失效


mysql存储引擎

存储引擎就是存储数据,建立索引,更新、查询数据等技术的实现方式。存储引擎是基于表的。mysql支持多种存储引擎,而oracle、sqlserver等只有一种存储引擎

InnoDB

  • mysql默认存储引擎
  • 支持事务
  • mysql存储引擎中唯一支持外键
  • 存储方式:表结构存储在frm文件中,数据和索引存储在ibd文件中
  • 支持行锁

MyISAM

  • mysql5.5之前默认存储引擎
  • 不支持事务和外键,访问速度快,适合对事务没有要求的select、insert等
  • 存储方式:表结构存储在frm文件,表数据存储在MYD(MYData),表索引存储在MYI(MYIndex)

Memory

memory存储引擎将表数据存在内存中,表结构存储在frm文件中,数据存放在内存中,默认使用HASH索引,一旦服务关闭,表中的数据就会丢失

Merge

Merge存储引擎是一组MyISAM表的组合,这些MyISAM表的结构必须完全相同,Merge表本身不存储数据,对Merge类型的表可以进行查询、更新、删除操作,实际是对内部的MyISAM表进行操作。

  • 可以突破对单个MyISAM表的大小限制,并通过将不同的表分布在多个磁盘上,可以有效改善Merge表的访问效率。

B+树

B+树为B树的变种,区别为:
1)n叉B+树最多包含n个key,而B树最多包含n-1key
2)B+树的叶子节点保存所有的key信息,按key大小顺序排列
3)所有的非叶子节点都可以看做是key的索引部分
mysql中对B+树进行了优化,在B+树的基础上增加一个指向相邻叶子节点的连表指针,形成带有顺序指针的B+树,提高了区间访问的性能


sql优化

一、order by 优化
1)尽量减少额外排序,通过索引覆盖直接返回有序数据。where条件和order by使用相同索引,并且order by字段都是升序或降序,才会命中索引,否则会出现fileSort。
2)Filesort优化:
两次扫描算法先是取出排序字段和行指针,在排序区sort bufffer中排序,如果sort buffer不够,则在临时表temporary table中排序,再根据行指针回表读取记录,I/O占用高。
一次扫描算法是直接取出所有字段在sort buffer中排序直接输出结果,内存占用高,效率也更高。
mysql通过比较系统变量max_length_for_sort_data的大小和取出的字段总大小来判定用哪种算法。
可以适当提高max_length_for_sort_data和sort_buffer_size来增大排序区的大小,提高排序效率。
二、group by 优化
1)利用索引覆盖原则
2)group by 内部默认进行了排序,可以通过order by null来禁用排序
三、子查询优化
1)尽量使用多表联查替换子查询
四、or优化
1)or如果要命中索引,需使用单列索引,不能命中复合索引
2)使用union替换or
五、limit优化
limit分页在页数大的时候会很慢,可以通过以下方案优化
1)在索引上完成分页操作,再通过索引关联查询其他列的内容
2)针对于主键自增的表且主键不会出现断层,可以把limit查询装换成某个位置的查询。
六、索引提示
1)use_index建议使用某个索引(mysql不一定会使用)
2)ignore_index忽略一个或多个索引
3)force_index强制使用某个索引


应用优化

一、使用数据库连接池
二、减少对mysql的访问
1)避免重复查询
2)增加cache层
三、负载均衡
1)通过主从实现读写分离
2)采用分布式数据库架构

查询缓存

  • 查询数据库是否支持查询缓存:show variables like 'have_query_cache'
  • 查询数据库是否开启查询缓存:show variables like 'query_cache_type'
  • 查询数据库缓存大小:show variables like 'query_cache_size'
  • 查看查询缓存的状态变量:show status like 'Qcache%'
    mysql查询缓存默认是关闭的,需要手动配置参数query_cache_type开启

一、查询缓存select选项
通过SQL_CACHE或SQL_NO_CACHE来指定该sql是否走缓存
二、查询缓存失效情况
1)SQL语句不一致
2)当查询语句中有一些不确定的函数时不走缓存,例如:now()、uuid()等
3)没有查询任何表时不走缓存
4)查询mysql系统数据库时不走缓存
5)在存储函数的触发器或事件的主体内执行查询不走缓存
6)若表发生更改,该表对应的所有缓存失效

内存优化

一、内存优化原则
1)将尽量多的内存分配给mysql做缓存
2)MyISAM存储引擎的数据文件读取依赖于操作系统自身的IO缓存,因此,如果是MyISAM表就要预留更多的内存给操作系统做IO缓存
3)排序区、连接区等缓存是分配给每个数据库会话的,其默认值的设置要根据最大连接上合理配置
二、MyISAM内存优化
MyISAM存储引擎使用key_buffer缓存索引块,而对于数据块则没有缓存机制,完全依赖于操作系统的IO缓存
1)key_buffer_size决定MyISAM索引块缓存区大小,建议至少分配可用内存的1/4
2)read_buffer_size是每个session独占的,如果经常需要顺序扫描可以适当增大read_buffer_size来改善性能
3)对于需要排序的MyISAM表若带有order by子句,适当增加read_rnd_buffer_size的值可以改善性能
三、InnoDB内存优化
InnoDB用一块内存去做IO缓存池,同时缓存索引和数据
1)innodb_buffer_pool_size决定缓存区的大小,提高该缓存区大小可以提高缓存的命中率
2)innodb_log_buffer_size决定重做日志缓存的大小,适当提高可以避免innodb在事务提交前日志写磁盘的动作
四、mysql并参数调整
1)调整最大连接数max_connections
2)调整积压请求栈的大小back_log
3)调整线程可打开表缓存数量table_open_cache
4)thread_cache_size控制mysql缓存客户服务线程的数量
5)innodb_lock_wait_time设置行锁的等待时间


mysql锁

锁分类

数据库操作粒度:
1)表锁
2)行锁:innodb默认支持,开销大,加锁慢;锁粒度低,发生锁冲突的概率也低,并发读高
3)页面锁
数据操作类型粒度:
1)读锁(共享锁):阻塞写,不阻塞读
2)写锁(排它锁):阻塞写,也阻塞读

innodb事务

ACID属性

  • 原子性(Atomicity):事务是一个原子操作,要么全部成功,要么全部失败
  • 一致性(Consistent):在事务开始和完成时,数据都必须保持一致状态
  • 隔离性(Isolation):数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的“独立”环境下运行
  • 持久性(Durable):事务完成之后对数据的修改时永久的

事务的隔离级别

  • 读未提交(read uncommitted):事务中的修改,即使没有提交,对其他事务也是可见的
  • 读已提交(read committed):事务中的修改,只有已提交的才能可见
  • 可重复读(repeatable read):同一个事务中,多次读取同样记录的结果是一直的,mysql默认的隔离级别
  • 串行化(serializable):最高的隔离级别,读取每一行数据都加上锁,可能导致大量的超时和锁竞争

并发事务带来的问题

  • 丢失更新:最初事务修改的值会被后面的事务修改的值覆盖
  • 脏读:事务可以读取未提交的数据
  • 不可重复读:读取记录前后可能出现不一致
  • 幻读:当某个事务A在读取某个范围内的记录时,另外一个事务B又在该范围插入新的记录,当事务A再次读取该范围的记录时,会产生幻行。
    ps:不可重复读的重点在于update和delete,而幻读在于insert

innodb行锁

  • 对于update、delete和insert,innodb会默认加排它锁
  • 对于select语句,innodb不会加任何锁

innodb锁升级

如果不通过索引条件检索数据,那么innodb将对表的所有记录加锁,实际效果跟表锁一致

innodb间隙锁

当查询用范围条件时,innodb会给符合条件的已有数据进行加锁,当该范围中有不存在的记录,也会加锁

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

推荐阅读更多精彩内容

  • 好久没更新简书了,最近遇上一些事情拖慢了读书进度,望见谅!由于本书篇幅较大,所以我决定今后每看完一章就更新一章的笔...
    小炼君阅读 1,210评论 0 48
  • 1. 了解SQL 1.1 数据库基础 ​ 学习到目前这个阶段,我们就需要以某种方式与数据库打交道。在深入学习MyS...
    锋享前端阅读 1,047评论 0 1
  • 一 架构 MySQL的架构实现主要可以分成三层:接入层,服务层,引擎层 接入层负责网络连接管理,授权认证等功能,包...
    东方胖阅读 473评论 0 1
  • 一、什么是MySQL MySQL是一个关系型数据库管理系统,由瑞典 MySQLAB公司开发,目前属于 Oracle...
    紫荆秋雪_文阅读 217评论 0 0
  • 数据库:数据库是存储数据的仓库数据库管理系统(DBMS):是一种操作和管理数据库的大型软件,mysql:免费,开源...
    恬恬i阿萌妹O_o阅读 161评论 0 0