MySQL(二) MySql经常使用优化

在上一篇博客中简单的介绍了下MySql的索引,在本篇博客中将进一步介绍MySql的索引以及经常使用的Mysql优化。

1、常见的树结构: 

  • 二叉树:每一个父节点大于左孩子节点,小于右孩子节点 。
  • 平衡二叉树:二叉树的基础上,每一个节点的子树高度差不大于1 。
  • BTree:是一种平衡多路搜索树,另外并保证了每一个叶子结点到根节点的距离相同,每一个节点保存了data
  • B+Tree:非叶子结点只存放key,叶子节点存储key,data.叶子节点能够包含一个指针指向另外一个叶子节点以加速顺序存取。

2、MySql存储引擎 

  • InnoDB存储引擎 当前MySQL存储引擎中的主流,InnoDB存储引擎支持事务、支持行锁、支持非锁定读、支持外键。 
  • MyISAM存储引擎 MyISAM不支持事务,不支持行级锁,支持表锁(效率低),支持全文索引,最大的缺陷是崩溃后没法安全恢复。

在InnoDB和MyISAM中索引都采用了B+Tree结构,可是实现方式并不相同:mysql

  1. 在MyISAM中叶子节点的data域并不存放数据而是存放数据记录的地址,因此MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,若是指定的Key存在,则取出其data域的值,而后以data域的值为地址,读取相应数据记录。
  2. 在InnoDB中有汇集索引和非汇集索引(辅助索引):
    • 汇集索引:非叶子结点存放的是<key,point>,point就是指向下一层的指针。 叶子结点保存了这一行的信息,所以经过主键索引能够快速获取数据。InnoDB中一般主键就是一个汇集索引。准确来讲汇集索引并非某种单独的索引类型,而是一种数据存储方式。就是指在同一个结构中保存了B+tree索引以及数据行。 innoDB中,用户若是没有设置主键索引,会随机选择一个惟一的非空索引替代, 若是没有这样的索引,会隐式的定义一个主键做为隐式的汇集索引。
    • 非汇集索引:非汇集索引的叶子结点并无存放数据,而是存储相应行数据的汇集索引键,即主键。当经过非汇集助索引来查询数据时,InnoDB存储引擎会遍历非汇集索引找到主键,而后再经过主键在汇集索引中找到完整的行记录数据。

3、总结

使用B+Tree做为索引结构的缘由:算法

    • B-Tree每一个节点中不只包含数据的key值,还有data值。而每个页的存储空间是有限的,若是data数据较大时将会致使每一个节点(即一个页)能存储的key的数量很小,当存储的数据量很大时一样会致使B-Tree的深度较大,增大查询时的磁盘I/O次数,进而影响查询效率。在B+Tree中,全部数据记录节点都是按照键值大小顺序存放在同一层的叶子节点上,而非叶子节点上只存储key值信息,这样能够大大加大每一个节点存储的key值数量,下降B+Tree的高度。

4、MySql经常使用优化

  1. 索引失效的状况
    • 以%开头的like查询
    • (not , not in, not like, <>, != ,!>,!<)不会使用索引
    • 若是条件中有or,即便其中有部分条件带索引也不会使用
    • where 子句里对索引列上有数学运算或者使用函数,用不上索引
    • 索引列的数据类型存在隐形转换则用不上索引。好比字符串,那必定要在条件中将数据使用引号引用起来
  2. sql优化 
    • 分解关联查询:将关联(join)放在应用中处理,执行简单的sql,好处是:分解后的sql一般因为简单固定,能更好的使用mysql缓存。还能够能够减小锁的竞争。
    • SELECT子句中避免使用*号 ,它要经过查询数据字典完成的,意味着将耗费更多的时间,并且SQL语句也不够直观。
    • 关于Limit 在使用Limit 2000,10这种操做的时候,mysql会扫描偏移量(2000条无效查询)数据,而只取后10条,尽可能想办法规避。
    • 一般状况下,使用一个性能好的sql代替使用多个sql。除非这个sql过长效率低下或者对于delete这种语句,过长的delete会致使太多的数据被锁定,耗尽资源,阻塞其余sql。 
    • WHERE子句中的链接顺序 数据库采用自右而左的顺序解析WHERE子句,因此那些能够过滤掉最大数量记录的条件最好写在WHERE子句的最右。 
    • 选择最有效率的表名顺序 数据库的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表将被最早处理 在FROM子句中包含多个表的状况下: 若是是彻底无关系的话,将记录和列名最少的表写在最后。若是是有关系的话,将引用最多的表,放在最后。
    • 删除全表数据用TRUNCATE替代DELETE 这里仅仅是:DELETE是一条一条记录的删除,而Truncate是将整个表删除,保留表结构,这样比DELETE快
    •  多使用内部函数提升SQL效率 
    • 使用表或列的别名,使用简短的别名也能稍微提升一些SQL的性能。毕竟要扫描的字符长度变少了 
    • 用 >= 替代 > ,低效:> 3首先定位到=3的记录而且扫描到第一个大于3的记录。高效:>= 4 直接跳到第一个等于4的记录 
    • 用IN替代OR 
  3. 数据库结构优化
    • 表结构优化:字段尽可能使用非空约束,由于在MySql中含有空值的列很难进行查询优化,NUll值会使索引以及索引的统计信息变得很复杂 
    • 数值类型的比较比字符串类型的比较效率要高得多, 
    • 尽可能使用TIMESTAMP而非DATETIME(查询效率)
    • 单表不要有太多的字段,建议在20之内 
    • 合理加入冗余字段
    • 垂直表拆分 水平表拆分 





参考博文: blog.csdn.net/u013235478/…
相关文章
相关标签/搜索