zoukankan      html  css  js  c++  java
  • 数据库:索引-引擎-优化

    使用索引就是为了查询数据效率快

    索引就是一种数据结构,它的数据结构就是平衡树,也就是B tree或者B + tree

    数据库索引:

    1、普通索引,最基本的索引,它没有任何限制

    2、唯一索引,与普通索引不同的就是,索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。

    3、主键索引,是一种特殊的唯一索引,不允许有空值。一般是在建表的时候提示创建主键索引,记住:一个表只能有一个主键

    4、组合索引,将多个字段合在一起 来创建索引。

    5、全文索引:只能用于MyISAM类型的数据表,只能用于CHAR ,VARCHAR,TEXT数据列类型


    非聚集索引和聚集索引的区别在于, 通过聚集索引可以查到需要查找的数据, 而通过非聚集索引可以查到记录对应的主键值 , 再使用主键的值通过聚集索引查找到需要的数据
    聚簇索引(聚集索引):索引文件与数据文件不分离,数据文件本身就是索引文件。数据结构中叶子结点存储所有的数据。
    非聚簇索引(非聚集索引):索引文件与数据文件分离。数据结构中叶子结点存储的数据是指向数据文件某一行数的物理地址。

    Mysam存储引擎的索引就是非聚簇索引,其索引文件和数据文件是分离的。

    Innodb存储引擎的索引是一种聚簇索引,数据文件本身就是索引文件,data域中完整的保存了所有的数据信息。
    对于Innodb存储引擎,如果要想使用索引必须存在着主键列,即使在建表时不定义主键列,在创建索引时,数据库会隐式的添加主键字段作为主键列然后创建索引。


    我们已经学会了建立索引,那么我们需要在什么情况下建立索引呢?一般来说,在WHERE和JOIN中出现的列需要建立索引,但也不完全如此,因为MySQL只对<,<=,=,>,>=,BETWEEN,IN,以及某些时候的LIKE才会使用索引。

    创建索引的不足之处:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。

    建立索引会占用磁盘空间的索引文件。一般情况这个问题不太严重,但如果你在一个大表上创建了多种组合索引,索引文件的会膨胀很快。
    索引只是提高效率的一个因素,如果你的MySQL有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询语句。


    索引注意事项

    1、索引不会包含有NULL值的列
    只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL。

    2、使用短索引
    对串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个CHAR(255)的列,如果在前10个或20个字符内,多数值是惟一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。

    3、索引列排序
    MySQL查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。

    4、like语句操作
    一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引而like “aaa%”可以使用索引。

    5、不要在列上进行运算

    6、不使用NOT IN和<>操作


    无效索引
    A:尽量不要在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描
    B:应尽量避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描。
    C:应尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描
    select id from t where num=10 or Name = ‘admin’

    可以这样查询:

    select id from t where num = 10 union
    select id from t where Name = ‘admin’
    union all 返回所有数据,不管是不是重复。 union会自动压缩,去除重复数据。

    D:不做列运算
    where age + 1 = 10,任何对列的操作都将导致表扫描,它包括数据库教程函数、计算表达式等

    E:查询like,如果是 ‘%aaa’ 不会使用到索引

    注意:IN 的条件过多,会导致索引失效,走索引扫描

    IN 的条件过多,返回的数据会很多,可能会导致应用堆内内存溢出。所以必须要控制好IN的查询个数


    MySQL在5.6版本开始采用Innodb,之前都是Myisam作为默认引擎
    Innodb支持事务,myisam不支持事务
    Innodb中B+Tree,主键索引叶子节点存储的不再是数据对应的存储位置,而是数据本身;辅助索引叶子节点存储的是数据对应的主键索引,命中后拿到对应的主键索值再去主键索引中搜索到具体的值返回。
    Myisam中B+Tree 的叶子节点存存的是据库中对应数据的地址,再通过地址命中查找的数据并返回,主键和辅助索引为同级别索引

    什么是B+树结构?

    1. B+树结构是一种多路查找树的结构,该数据结构有以下特点:
    2. 根节点至少有两个子结点。
    3. 非根节点至少有m/2个关键字和子结点,至多有m个关键字和子结点。
    4. 非叶子结点不保存数据,只保存关键字,只起到索引的作用。
    5. 非叶子结点的关键字全部存在于叶子结点。
    6. 叶子结点存储所有关键字和数据,叶子结点按照关键字从小到大顺序链接。

    为什么选用B+Tree

    B+树是B-树的变种的多路绝对平衡查找树,他拥有B-树的优势
    B+树扫库、表能力更强
    B+树的磁盘读写能力更强
    B+树的排序能力更强
    B+树的查询效率更加稳定

    b+树有个特点,数据都是存在子节点上(叶子节点),其它节点只存索引,数据都是存在叶子节点上,而且叶子节点是有序的,在查询时有更高效率,而且这样的结构,不用存下一个节点磁盘位置信息,降低树的高度,而且节约空间,由于数据都存在叶子节点上,查询的次数恒定并且保证了查询速度。


    SQL优化
    1、建立适当的索引,优先考虑where、group by使用到的字段,尽量避免在字段开头模糊查询,会导致数据库引擎放弃索引进行全表扫描
    2、尽量避免select * 尽可能避免全表扫描
    3、尽量避免使用in、not in、or 会导致数据库引擎走全表扫描
    4、使用表别名、分表分库
    5、减少无效数据的查询,合理使用最左前缀原则


    Mysql如何保证一致性和持久性

    MySQL为了保证ACID中的一致性和持久性,使用了WAL(Write-Ahead Logging,先写日志再写磁盘)。Redo log就是一种WAL的应用。当数据库忽然掉电,再重新启动时,MySQL可以通过Redo log还原数据。也就是说,每次事务提交时,不用同步刷新磁盘数据文件,只需要同步刷新Redo log就足够了。


  • 相关阅读:
    多线程编程(一)
    所谓费曼学习法
    Java 基本数据类型扩充
    好记性不如烂笔头
    Java_面试札记
    Stream替代for-编码五分钟-划水五小时
    为什么启动线程是start方法?
    Java面试札记
    Tree
    手写SpringMVC 框架
  • 原文地址:https://www.cnblogs.com/liangxr/p/13870146.html
Copyright © 2011-2022 走看看