mysql

MySQL

  • mysql b tree每个节点怎么存储B-Tree和 B+Tree的数据存储结构温斯顿1984的博客-CSDN博客

  • 影响mysql性能的因素

    1. 商业需求影响性能,一些需要实时处理数据的需求(但是这个需求只有极少数一部分的用户需要),时刻数据同步肯定影响mysql的性能

    2. 系统架构及实现:因为mysql是和硬盘交互的,这个层面不是很好优化,在软件架构系统优化的性价比要高很多,比如尽量少让请求到mysql,mysql是硬盘级别的,而一些缓存如redis是内存级别的,速度肯定是快很多的

      1. 不适合在数据库中存放的数据:二级制多媒体数据,流水队列数据(因为流水量太大,源源不断的过来),超大文本数据

      2. 是否合理的利用了应用层Cashe机制

      3. 过度依赖数据库sql语句的功能造成数据库操作效率低下(比如有的比较长的sql语句可能还没有拆分成多条sql语句执行的快)

    3. 表设计对系统性能的影响:比如金融系统(冷热数据分离,不变的数据可以放到缓存里面),登录信息和账户信息就不要设计在一张表里面,因为登录信息是很少变动的,也是不需要事务保证安全的,但是账户信息是经常变动的,而且要事务保证安全,因为钱不能出差错,所以,如果在一张表里面的话,那么每次用户登录都需要走下事务,导致性能变差

    4. 硬件对系统性能的影响

    5. query语句对系统性能的影响

  • 优化

    1. 建立索引,生活中的字典就有拼音索引,通过拼音找到我们需要的字,后面跟的页码就是我们的索引,比如我现在要从一堆数字(1,3,5,7,9,10)里面去找到7这个数字,如果没有索引没有主键,那么就只能整个遍历,但是我加了索引,把它变成了二叉树,小的在左边,大的在右边,那么查询的时候就可以先判断一下范围再查询,查询的次数最多就是树的高度,时间复杂度是log(n),当数据量很大的时候,速度会比不做索引的快很多,但是它的代价就是把数据变复杂了占用了更多的存储空间

    2. 索引类型:B+TREE;Hash;FullText;R-Tree,innoDB中只有B+TREE;Hash这两个,hash适用于冲突不大的情况,如果冲突很大的话,那些冲突的数据就会形成链表,性能就会变差

    3. mysqlInnoDB存储引擎是支持hash索引的,但是hash索引的创建由innoDB存储引擎自动优化创建,我们干预不了,我们自己创建只有选择B+TREE

    4. B tree 一个节点可以放多个数据,限制是自己设置的,比如我的上限不超过3个,那么我一个节点放两个数据是没有问题的,但是当该节点加入第三个数据时,就会分裂,而B+Tree是B Tree的变种,数据结构是一样的,区别是B tree的非叶子节点也和叶子节点一样除了存放元素之外,还存储数据,而B+tree,只有叶子结点才会存储数据,非叶子结点只存放元素和导航指针(指针占用的空间是非常小的),并且所有的叶子节点都有一个链指针

    5. 系统从磁盘读取数据到内存时,是以磁盘块(block)为基本单位,位于同一个磁盘块的数据会被一次性读取出来,并不是需要什么就读取什么,innodb引擎中有页的概念,页是innodb和磁盘交互的最小单位,而我们的系统磁盘块(block)的空间往往是达不到16kb的,所以每次innodb从磁盘拿数据时就需要一次性拿好几个磁盘块(block)的数据来凑齐一页的大小(16kb),树的每一个节点就是一次io操作,每次操作只能拿到16kb的数据,所以在16kb固定的情况下,单个数据的大小越小,那么节点存储的数据就越多,如果节点能存放的数据越多,那么树的高度就越矮,树越矮,那么查询的速度就越快(因为树越矮,io操作就越少,性能消耗就越少)

    6. 磁盘IO操作应该是树高减1,因为不论走树的左边还是右边,始终都是要过根节点的,所以mysql会将根节点缓存起来,因为不确定下一次是走左边还是右边,所以只会缓存根节点,不会缓存其他的节点,所以IO操作的次数是树高减1

    • 索引

      1. 主键就是主索引

      2. 如果没有主键,那么mysql会选择非空且唯一的一列来作为主索引

      3. 如果既没有主键,也没有非空且唯一的列,那么mysql会建立一个隐藏列(有个自增的id)来作为主索引

      4. 除了主键以外,自己添加的索引就是辅助索引

      5. 创建索引的命名规范(名字全部小写,可以简写,不要超过太长):1.普通索引(idx_表名索引字段或直接使用idx索引字段名),示例:(alter table 表名 add index 索引名(索引列名),如:alert table order add index id_order_sno(sno)),2.唯一索引(uniq_表名字段名,或者直接uniq字段名),示例:alter table product add unique uniq_sid(sid),3.主键索引alter table product add primary key 索引名字(sid),4.组合索引创建,alter table student add index idx_age_name,height(age,name,height)

      • MyISAM

        1. 主索引都在myi文件中,索引中存储的都是数据的地址,拿到地址去myd中去查找数据

        2. 辅助索引也是在myi文件中,同上也是存储的数据地址,去myd中拿数据,区别就是,主索引是唯一且不为空的,而辅助索引是没有这个要求的(辅助索引是可以重复的)

      • innodb

        1. 主索引与数据是在一起的,找到了主索引也就找到了数据,数据存放在节点的data域中

        2. 辅助索引的叶子节点存储的是主索引的值,所以要查看完整的数据,还得通过这个值找找到主索引

      • 区别:

        1. 如果是通过主索引来找数据那么innodb是比myISAM快的,因为innodb的的数据是放在叶子节点的,和主索引在一起,找到了索引也就找到了数据,但是MyISAM的叶子节点存放的是数据的地址,还要通过地址去找数据,索引对于通过主索引来查找数据而言innodb要快点

        2. 但是如果是通过辅助索引来找数据的话,那么就是MyISAM要快点,因为innodb中辅助索引的叶子节点存放的是主键索引值,还要再走一遍主键索引才能找到数据,而MyISAM辅助索引和主索引是一样的逻辑都是叶子节点存放数据地址,再根据地址查找数据(不同点是辅助MyISAM的索引可以重复)

        3. 什么是聚簇索引:索引与数据放在一起的(比如innodb的主键索引)

        4. 什么是非聚簇索引:索引与数据不在一起的(innodb的辅助索引和MySIAM的索引)

      • 索引的优缺点

        1. 索引可以提高数据的检索效率

        2. 如果排序的列是索引列,可以大大降低排序的成本

        3. 在分组操作中如果分组的条件是索引,那么也会提高效率

        4. 建立索引需要占用一定的空间,维护索引也需要成本

      • 如何创建索引

        1. 索引的目的是帮助我们提高检索速度,不出现在where子句的字段不要加索引,因为没用上,我们的新增,删除,修改,对应的索引树是会变化的,是需要额外维护的,而我们加索引的目的是为了提高检索速度的,你都没出现在where子句中,就证明都没有查你,那这时建立索引不仅没用,还会增加额外的开销

        2. 频繁作为查询条件的字段应该加上索引

        3. 更新非常频繁的字段不适合创建索引,因为字段更新势必会影响到索引,维护索引需要额外的开销

        4. 唯一性太差的字段也不适合创建索引,即使它是频繁作为查询条件的字段,比如男和女的字段,就两种情况,如果我有1千万数据,最多也就只能区分一半,唯一性太差,所以不适合建立索引

        5. 单值索引即一列作为索引,组合索引即多列作为索引,组合索引从左到右是有要求的,比如我们有sql语句select * from student where age=18 and height = 180 and weight = 70 创建了组合索引(age,height,weight),情况一:如果三个值都有,那么索引顺序和where子句后面索引列的顺序没有影响,情况二:如果where子句中没有age条件,那么索引就不生效了,因为索引生效是从age开始的,情况三:如果where子句中没有height条件,那么就只有age索引能生效,在height的时候就被阻断了,所以weight也不生效了,情况四:如果where子句中只有heigth和age,且顺序是height在前age在后,那么age和height索引是可以生效的,因为height和age是相邻的,mysql会自动帮我们优化调整顺序(即相邻的顺序不一样没有影响),但是如果没有age条件那么后面的是不生效的,因为age是在第一个位置,没有他索引就被阻断了,所以建立组合索引的时候要把出现频次最高的索引列放在最左边(最左前缀原则)

        6. 为什么索引最好不为空呢?因为不为空的索引就只有一个索引结构,而可以为空的列设置索引,那么索引就要开辟两块空间,一块存储非空的,一块存储空的

      • 索引选择性与索引前缀

        1. 索引选择性:是指索引列中不同列值的数目与记录数的比,比如我现在有2000条数据,索引列有1500个不同的值,那么索引的选择性就为1500/2000=0.75

        2. 索引的选择性越接近1,那么这个索引的效率就越高,当索引选择性越接近于0,就越没必要建立索引

        3. 当数据量小的时候是没必要建立索引的,因为全表扫描花的时间就不多,建立索引提升的速度意义不大,一般以2000条数据为分界线,多余2000的才考虑

        4. 建立索引的时候也要考虑索引字段不要太长,10个长度的索引肯定是比30个长度的索引要匹配的快的(索引字段的长度就是我们建立表字段给的长度,比如name给了25,age给了16等)

      • 索引失效情况:

        1. 在复合索引中,最左索引条件没有满足

        2. 在复合索引中,使用or的情况,其中一个条件没有匹配到索引,会导致索引失效走全表扫描

        3. 当使用like进行模糊查询时,后缀查询会导致索引失效,前缀查询不会

        4. 当使用复合索引时有范围查询,那么范围条件后的索引就失效了(特列:between也是查范围,但是它实际上是相当于in,是精确查询,所以不会导致索引失效)

        5. 在查询表达式中使用了函数表达式(比如:left(name,4)会导致失效

        6. 还有在查询表达式中使用了算术运算,如select * from emp where no - 1 = 21会使索引失效),但是select * from emp where no = 22这样是不会导致索引失效的,所以不要给有索引的列(no)做任何运算

      • innodb主键选择与插入优化

        1. 尽量选择有自增的字段,因为数据最终是存入磁盘的,如果是自增的,那么我们在磁盘上申请和操作的空间就是连续的,如果一会大一会儿小,那么我的数据一会要插左边一会要插在右边,会导致需要申请很多的空间,空间没用完又会产生许多的碎片,影响性能
      • join优化原则

        1. 因为join是将两张表连在,如果A表有100条数据,B表也有100条数据,那么数据比较的次数就是100100=1W次(产生1w的笛卡尔积),如果AJonB时on后面的条件本身就有索引,那么比较的次数等于A的数据量100树高,比如树高为3,那么比较的次数就是300次,找到索引就可以快速找到数据

        2. 小结果集驱动大结果集==》目的是减少内层访表次数(mysql内部帮我们做了优化),即把结果集小的表作为外表,就是左边的

        3. 可以使用STRAIGHT_JON,指定驱动表和被驱动表

        4. 为匹配的条件增加索引,A为驱动表,B为被驱动表,关联条件(on)为A.age=B.age,那么在B.age字段添加索引,可以减少匹配次数(就是上述第一条的例子)

        5. 增大join_buffer_size的大小(join_buffer_size的作用是将外表的数据缓存起来,然后一次性去访问内表),这个缓存一次性缓存外表的数据越多,那么外表访问内表的次数就越少,默认的大小是256k,可以使用show variables like 'join_%'查看,可以在mysql的配置文件my.ini中配置缓存区大小:在[mysqld] 这个节点下配置:join_buffer_size = 8M

        6. 减少不必要的字段查询,比如写select *(单条记录大小为1M),select 需要字段(单条记录大小为0.1M),那么在join buffer size固定的情况下,单条记录越小,能容纳的数据就越多,减少对内层表的访问

        • order by优化

          1. 单路排序的性能比双路排序的性能高,因为双路排序要经历两次读,第一次是顺序的,第二次是乱序的,

          2. 单路排序直接把需要的数据放到内存,然后从内存里面读数据,所以比双路排序要快

          3. 若果sql语句需要排序,根据你select返回字段的总长度是否大于max_length_for_sort_data来判断,如果大于这个值走双路,小于走单路,排序时<固定长度的排序列,需要返回的列>一起组成元组,放入sort buffer中

          4. 单路排序的元组比双路排序的要长,导致它需要多次向临时文件写入内容,增加io操作,当需要返回的列的总长度很长时尤其明显

          5. MySQL根据max_length_for_sort_data变量来确定使用哪种算法,默认值1024字节,如果需要返回的列的总长度大max_length_for_sort_data,使用双路,否则使用单路。

            • 优化

              1. 加大max_length_for_sort_data参数

              2. 去掉不必要的返回字段(比如不要用select*)

              3. 增大sort——buffer——size参数

          6. 如果是多个表联合排序时,排序的字段是被驱动表,那么肯定就会出现临时表和之后排序,临时表(临时表包含两个表的字段,非常容易走双路排序,产生的临时文件也比较多),可以使用STRAIGHT_JOIN调整驱动表和被驱动表的关系

        • 优化sql

          1. 开启慢查询日志,超过2秒的sql会记录下来,通过explain命令和profile查看sql执行计划和资源消耗,主要查看sql是否用上索引,索引是否由于某些原因失效,是否有出现临时表

          2. 永远用小结果集驱动大结果集

          3. 在索引中完成排序

          4. 使用最小的columns

            1. 特别是需要使用column排序的时候;

            2. 减少网络传输数据量;

            3. MYSQL排序原理,是把所有的column(列)数据全部取出,在排序缓存区排序,再返回结果;如果column数据量大,排序区容量不够的时候,就会使用先column排序,再取数据,再返回的多次请求方式;

        • mysql主从复制

          1. 在主节点的配置文件中配置bin-log文件,目的是存储mysql主节点的DML(增删改)操作

          2. 重启mysql服务,启动线程把DML,DDL操作记录到bin-log文件中

          3. 在从节点的配置文件中配置relay-log文件,存储主节点的DML,DDL操作

          4. 主从复制采取的是被动注册的方式,由从节点给主节点发送要求同步的命令,启动从节点模式,发送命令时需要知道哪些信息呢?1.主节点的地址端口,2.主节点的账号密码,3.需要同步主节点中的哪个文件,4.以及3中所说额文件的哪个位置开始同步

          5. 主节点收到从节点的同步请求后,会启动线程把bin-log的文件内容以二进制的方式通过网络传输到从节点

          6. 从节点会启动一个线程来接收主节点发来的数据存入到relay-log文件中

          7. 从节点再启动一个线程把relay-log中内容在数据库中重做一遍(重做的效率是很快的,比我们自己写的普通sql要快很多,因为普通sql的执行要权限验证,解析优化等,而我们是从主节点bin-log中复制来的,是被主节点执行过的,所以在从节点重做时是无须那些额外操作的)

          8. 因为主从复制需要走网络传输,所以可能存在网络波动的情况,是无法保证一定准确的,此时我们可以把重要数据的读写都在主节点执行,而一些不重要的信息(比如日志等)到从节点进行

Mycat

mycat原理.png
  • 原理:

    1. Mycat实现了和MySql一样的sql标准,应用程序连接MyCat和直接连接数据是一样的,是感觉不到差别的,在mycat中要配置逻辑表和真实表的关系,因为mycat是用java写的,所以在安装mycat之前必须具备jdk的环境

    2. mycat里面有一个逻辑库和逻辑表的概念,我们连接其实是连接的mycat的逻辑库,再由逻辑库去找到我们真实的库,逻辑库的名字可以和真实库的名字不一样

    3. 应用程序发送一个去t_order表中查询的语句,其实操作的是逻辑表,再由逻辑表进行sql语句进行分发,如果是写操作就给主节点执行,如果是读操作就给从节点执行,当主节点有操作执行时会同步到从节点,在mycat中配置了主从节点,读写分离后,正常情况下读是不会去主节点去读,但是可以通过mycat的注解来强制要求去主节点读

    • 配置

      1. server.xml:mycat相关的配置:端口,线程池,账号密码,黑名单、白名单,表权限操作等,mycat默认的端口是8066,用户名密码root/123456

      2. rule.xml:分片规则

      3. schema.xml:配置逻辑库逻辑表和真实库真实表的映射关系

    • 分库分表

      1. 当数据超过500w时,数据库的性能会明显下降,所以才有了分库分表的需求

      2. 垂直拆分,比如以前有商品,订单,支付操作的都是同一个库,现在它们各自有自己对应的数据库,这就是垂直拆分

      3. 水平拆分,比如以前订单系统只有一个数据库,现在水平横向扩展加了两个库,那么订单系统就有了三个数据库

    • 如何实现分片


      mycat如何实现分片.png
      1. 在mycat中要配置分片字段和规则,比如orderNo作为分片字段,分片规则为:求模取余(比如我们现在分了三片,即分了3个数据库,那么就对orderNo%3求余,得到的余数是多少,交把sql语句交给哪个数据库节点执行)

      2. 在执行sql语句的时候是insert的时候就是按照1中所说的规则分配,只有分配到的节点执行sql,其余的节点mycat是不会给它们发送sql语句的

      3. 如果执行的是select语句,如果语句中有orderNo条件,那么也会按照1中的规则去分配

      4. 如果select语句中没有orderNo条件,那么mycat会给每个节点都发送sql去执行,然后在mycat中进行结果的聚合处理再返回出去

      5. 同理如果有order by时,mycat也是给各节点发送sql执行,最后在mycat中进行结果的聚合和处理

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

推荐阅读更多精彩内容