MySQL 索引

欢迎光临我的博客[http://poetize.cn],前端使用Vue2,聊天室使用Vue3,后台使用Spring Boot

概念

索引是一种特殊的文件,它们包含着对数据表里所有记录的引用指针。

在没有索引的情况下,数据库会遍历全部数据后选择符合条件的;
有了相应的索引之后,数据库会直接在索引中查找出符合条件的选项。

使用场景

where    order by    join on(关联查询对数据库压力大,实际开发可能不用,采用单表查询)


MySQL有两种方式可以实现ORDER BY:

    1. 通过索引扫描生成有序的结果

    2. 使用文件排序(filesort)


索引扫描排序:
    MySQL会直接遍历字段索引的叶子节点链表,不需要进行额外的排序操作。

文件排序(filesort):
    先扫表筛选出符合条件的数据,再将筛选结果根据字段排序。


WHERE 子句和 ORDER BY 子句都可以使用索引:
	WHERE 子句使用索引避免全表扫描,
	ORDER BY 句使用索引避免 filesort。


ORDER BY 满足以下情况,会使用索引排序:
    ORDER BY 语句使用索引。
    使用 Where 子句与 Order BY 子句满足组合索引最左前缀。


order by:
    如果排序字段没有建立索引,那么执行计划会将查询出的所有数据使用外部排序,
    这个操作是很影响性能的,因为需要将查询涉及到的所有数据从磁盘中读到内存

    如果对该字段建立索引,那么由于索引本身是有序的,因此直接按照索引的顺序和映射关系逐条取出数据即可。
    而且如果分页的,那么只用取出索引表某个范围内的索引对应的数据,而不用像上述那取出所有数据进行排序再返回某个范围内的数据。
    (从磁盘取数据是最影响性能的)

普通索引

直接创建索引:
    CREATE INDEX index_name ON table(column(length));

修改表结构的方式添加索引:
    ALTER TABLE table_name ADD INDEX index_name ON (column(length));

创建表的时候同时创建索引:
    CREATE TABLE `table` (
        `id` int AUTO_INCREMENT,
        `title` char(128),
        PRIMARY KEY (`id`),
        INDEX index_title (title(64))
    );


删除索引:
    DROP INDEX index_name ON table_name;


没有任何限制,MyIASM中默认的BTREE类型的索引,也是我们大多数情况下用到的索引。

唯一索引

创建唯一索引
    CREATE UNIQUE INDEX index_name ON table(column(length));

修改表结构
    ALTER TABLE table_name ADD UNIQUE index_name ON (column(length));

创建表的时候直接指定
    CREATE TABLE `table` (
        `id` int AUTO_INCREMENT,
        `title` char(128),
        PRIMARY KEY (`id`),
        UNIQUE index_title (title(64))
    );


索引列的值必须唯一,但允许有空值(注意和主键不同)。如果是组合索引,则列值的组合必须唯一。

外键约束

foreign key:
    外键设置在副表上。
    外键引用主键字段所在的表叫做主表。


外键数据操作:
	1.当有外键约束之后,添加数据的时候,先添加主表数据,再添加副表数据
	2.当有了外键约束,修改数据的时候,先改副表的数据,再修改主表的数据
	3.当有了外键约束,删除数据的时候,也是先删除副表的数据,再删除主表的数据


外键定义语法:
	constraint  外键约束名称  foreign key(外键字段)  references  主表名称(引用字段);


一对多:

    CONSTRAINT `FK_ID` FOREIGN KEY (`gid`) REFERENCES `grade` (`id`)

    ALTER TABLE nobility ADD CONSTRAINT fk FOREIGN KEY (classid) REFERENCES class(id);


多对多:

    create table student_teacher (
	    student_id int,
	    teacher_id int,
	    foreign key (student_id) references student(id),
	    foreign key (teacher_id) references teacher(id)
    );


删除外键:

    alter  table  表名  drop  foreign  key  外键名;

组合索引(最左前缀)

ALTER TABLE article ADD INDEX index_title_time (title(10),time(10));

    建立这样的组合索引,其实是相当于分别建立了下面两组索引:
        –title,time
        –title


MySQL组合索引“最左前缀”:
    只从最左面的开始组合,并不是只要包含这两列的查询都会用到该组合索。


多个单列索引在多条件查询时优化器会选择最优索引策略:
    可能只用一个索引,也可能将多个索引全用上!
    但多个单列索引底层会建立多个B+索引树,比较占用空间,也会浪费一定搜索效率,故如果只有多条件联合查询时最好建联合索引!

全文索引(FULLTEXT)

利用【分词技术】等多种算法智能分析出文本文字中关键词的频率和重要性,然后按照一定的算法规则智能地筛选出我们想要的搜索结果。

MySql自带的全文索引只能对英文进行全文检索,目前无法对中文进行全文检索。


字段类型:
    char、varchar和text才能使用全文索引


分词:
    全文索引以词为基础的,MySQL默认的分词是所有非字母和数字的特殊符号都是分词符。全文匹配时忽略大小写。
    MySQL规定全文搜索中被搜索的单词所在的行数大于等于被搜索的所有行数的一半时候,就将被搜索单词作为Common word,即不被显示。


创建表的时候添加全文索引:
    CREATE TABLE `table` (
        `id` int AUTO_INCREMENT,
        `content` text,
        PRIMARY KEY (`id`),
        FULLTEXT ('content')
    );


修改表结构添加全文索引:
    ALTER TABLE article ADD FULLTEXT index_content(content);

直接创建索引:
    CREATE FULLTEXT INDEX index_content ON article(content);


查询:

    SELECT * FROM table_name WHERE MATCH (filed_1,filed_2) AGAINST ('keyword');

    SELECT * FROM table_name WHERE MATCH (filed_1,filed_2) AGAINST ('+keyword_1 -keyword_2' IN BOOLEAN MODE);
    返回包含keyword_1的数据,而包含keyword_2的数据就会被过滤掉。

    MATCH (girl_name) AGAINST ('+小红*')    --*只能接在字符串后面

    "tommy huang" 可以匹配 tommy huang,但是不能匹配 tommy is huang


对于较大的数据集:
    将资料输入一个没有FULLTEXT索引的表中,然后创建索引,其速度比把资料输入现有FULLTEXT索引的速度更为快。
    不过切记对于大容量的数据表,生成全文索引是一个非常消耗时间非常消耗硬盘空间的做法。

建立索引的优缺点

优点:
        可以加速表和表之间的连接(外键)

        可以保证数据库表中每一行数据的非空唯一性(主键) 

        加快数据的检索速度,这也是创建索引的最主要的原因。

        在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。

        通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。


缺点:
        第一、创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。 

        第二、索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间。

        第三、当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。


适合创建索引:

       第一、在经常需要搜索的列上,可以加快搜索的速度;

       第二、在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构;

       第三、外键,可以加快连接的速度;

       第四、在经常需要根据 范围进行搜索 的列上创建索引,因为索引已经排序,其指定的范围是连续的;

       第五、在经常需要 order by 的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;

       第六、在经常使用在 where 子句中的列上面创建索引,加快条件的判断速度。

 
不适合创建索引:

       第一,查询中很少使用的列不应该创建索引。由于增加了索引,反而降低了系统的维护速度和增大了空间需求。 

       第二,对于那些只有很少数据值的列也不应该增加索引。增加索引,并不能明显加快检索速度。 

       第三,对于那些定义为text, image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。 

       第四,当修改性能远远大于检索性能时,不应该创建索引。这是因为,修改性能和检索性能是互相矛盾的。
             当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。


查看表中索引的方法:

    show index from table_name;

参考

https://www.cnblogs.com/owenma/p/8575646.html

posted @ 2019-09-21 11:57  LittleDonkey  阅读(230)  评论(0编辑  收藏  举报