发表于: 2018-03-14 22:27:50

2 497


今天完成的事情:

MySQL索引:

一、首先是学习索引的知识点:

--建立索引可以大大的提高MySQL检索速度
--索引可分为单列索引组合索引  
单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。
组合索引,即一个索引包含多个列。
--创建索引时,需要确保索引是引用在sql查询语句的条件(一般作为where子句的条件)
--索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。
索引的缺点虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。建立索引会占用磁盘空间的索引文件。
  • 哪些情况需要创建索引
    ①主键自动建立唯一索引
    ②频繁作为查询条件的字段应该创建索引
    ④频繁更新的字段不适合建立索引,因为每次更新不单单是更新了记录还会更新索引
    ⑤WHERE条件里用不到的字段不创建索引
    ⑥单键/组合索引的选择问题,(在高并发下倾向创建组合索引)
    ⑦查询中排序的字段,排序的字段若通过索引去访问将大大提高排序速度
    ⑧查询中统计或者分组字段
  • 哪些情况不需要创建索引
①表记录太少
②经常增删改的表
    提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE、和
        DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。
    数据重复且分布平均的表字段,因此应该只为最经常查询和最经常排序的数据建立索引。

      ③注意,如果某个数据列包含许多重复的内容,为它建立索引就没有太大的实际效果


mysql索引类型normal,unique,full text的区别是什么?
  1. normal:表示普通索引
  2. unique:表示唯一的,不允许重复的索引,如果该字段信息保证不会重复例如身份证号用作索引时,可设置为unique
  3. full textl: 表示 全文搜索的索引。 FULLTEXT 用于搜索很长一篇文章的时候,效果最好。用在比较短的文本,如果就一两行字的,普通的 INDEX 也可以。
  4. spatial:空间索引。
  5. 总结,索引的类别由建立索引的字段内容特性来决定,通常normal最常见。



MySQL常用的btree索引和hash索引(方法)的区别:
Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-Tree 索引。
可能很多人又有疑问了,既然 Hash 索引的效率要比 B-Tree 高很多,为什么大家不都用 Hash 索引而还要使用 B-Tree 索引呢?任何事物都是有两面性的,Hash 索引也一样,虽然 Hash 索引效率高,但是 Hash 索引本身由于其特殊性也带来了很多限制和弊端,主要有以下这些。
(1)Hash 索引仅仅能满足"=","IN"和"<=>"查询,不能使用范围查询。
由于 Hash 索引比较的是进行 Hash 运算之后的 Hash 值,所以它只能用于等值的过滤,不能用于基于范围的过滤,因为经过相应的 Hash 算法处理之后的 Hash 值的大小关系,并不能保证和Hash运算前完全一样。
(2)Hash 索引无法被用来避免数据的排序操作。
由于 Hash 索引中存放的是经过 Hash 计算之后的 Hash 值,而且Hash值的大小关系并不一定和 Hash 运算前的键值完全一样,所以数据库无法利用索引的数据来避免任何排序运算;
(3)Hash 索引不能利用部分索引键查询。
对于组合索引,Hash 索引在计算 Hash 值的时候是组合索引键合并后再一起计算 Hash 值,而不是单独计算 Hash 值,所以通过组合索引的前面一个或几个索引键进行查询的时候,Hash 索引也无法被利用。
(4)Hash 索引在任何时候都不能避免表扫描。
前面已经知道,Hash 索引是将索引键通过 Hash 运算之后,将 Hash运算结果的 Hash 值和所对应的行指针信息存放于一个 Hash 表中,由于不同索引键存在相同 Hash 值,所以即使取满足某个 Hash 键值的数据的记录条数,也无法从 Hash 索引中直接完成查询,还是要通过访问表中的实际数据进行相应的比较,并得到相应的结果。
(5)Hash 索引遇到大量Hash值相等的情况后性能并不一定就会比B-Tree索引高。
对于选择性比较低的索引键,如果创建 Hash 索引,那么将会存在大量记录指针信息存于同一个 Hash 值相关联。这样要定位某一条记录时就会非常麻烦,会浪费多次表数据的访问,而造成整体性能低下。
当我们为某一列或某几列建立hash索引时(目前就只有MEMORY引擎显式地支持这种索引),会在硬盘上生成类似如下的文件:
hash值 
存储地址    
1db54bc745a1
77#45b5 
4bca452157d4
76#4556,77#45cc…
hash值即为通过特定算法由指定列数据计算出来,磁盘地址即为所在数据行存储在硬盘上的地址(也有可能是其他存储地址,其实MEMORY会将hash表导入内存)。
这样,当我们进行WHERE age = 18 时,会将18通过相同的算法计算出一个hash值==>在hash表中找到对应的储存地址==>根据存储地址取得数据。
所以,每次查询时都要遍历hash表,直到找到对应的hash值,如(4),数据量大了之后,hash表也会变得庞大起来,性能下降,遍历耗时增加,如(5)
《--普通索引--》
---创建索引
CREATE INDEX indexName ON mytable(username(length));
如果是CHAR,VARCHAR类型,length可以小于字段实际长度;如果是BLOB和TEXT类型,必须指定 length。
---修改表结构(添加索引)
ALTER table tableName ADD INDEX indexName(columnName)
---创建表的时候直接指定
CREATE TABLE mytable(  ID INT NOT NULL,   username VARCHAR(16) NOT NULL,  INDEX [indexName] (username(length))  );
---删除索引的语法
DROP INDEX [indexName] ON mytable;
《--唯一索引--》
它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。它有以下几种创建方式:
---创建索引
CREATE UNIQUE INDEX indexName ON mytable(username(length))
---修改表结构
ALTER table mytable ADD UNIQUE [indexName] (username(length))
创建表的时候直接指定
CREATE TABLE mytable(  ID INT NOT NULL,   username VARCHAR(16) NOT NULL,  UNIQUE [indexName] (username(length))  );  

使用ALTER 命令添加和删除索引
有四种方式来添加数据表的索引:
  • ALTER TABLE tbl_name ADD PRIMARY KEY (column_list): 该语句添加一个主键,这意味着索引值必须是唯一的,且不能为NULL。
  • ALTER TABLE tbl_name ADD UNIQUE index_name (column_list): 这条语句创建索引的值必须是唯一的(除了NULL外,NULL可能会出现多次)。
  • ALTER TABLE tbl_name ADD INDEX index_name (column_list): 添加普通索引,索引值可出现多次。
  • ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list):该语句指定了索引为 FULLTEXT ,用于全文索引。
以下实例为在表中添加索引。
mysql> ALTER TABLE testalter_tbl ADD INDEX (c);
你还可以在 ALTER 命令中使用 DROP 子句来删除索引。尝试以下实例删除索引:
mysql> ALTER TABLE testalter_tbl DROP INDEX c;

使用 ALTER 命令添加和删除主键
主键只能作用于一个列上,添加主键索引时,你需要确保该主键默认不为空(NOT NULL)。实例如下:
mysql> ALTER TABLE testalter_tbl MODIFY i INT NOT NULL; mysql> ALTER TABLE testalter_tbl ADD PRIMARY KEY (i);
你也可以使用 ALTER 命令删除主键:
mysql> ALTER TABLE testalter_tbl DROP PRIMARY KEY;
删除主键时只需指定PRIMARY KEY,但在删除索引时,你必须知道索引名。

显示索引信息
你可以使用 SHOW INDEX 命令来列出表中的相关的索引信息。可以通过添加 \G 来格式化输出信息。
尝试以下实例:

mysql> SHOW INDEX FROM table_name;


二、创建索引的操作

Navicat创建索引:



MySQL创建索引:

删除索引:

哪些字段还需要创建索引:
创建索引要求字段不会频繁更新,并且能够作为where查询,而且查询合理,所以我觉得类型、入学时间、学号、(create_at)录入时间都可以创建索引。


插入10条数据,SQL语句操作---->>
①:无索引的情况下



②:有索引的情况下

明天计划的事情:软件安装过了,学习maven、idea的使用,配置好环境。跟着往后面做。


遇到的问题:有无索引的对比那个地方,除开插入时候,时间存在差异(索引时间快一点)。进行查询的时候,两者的时间是一样的,我装了两个版本的Navicat,分别进行了操作,还是没有变化。还有我特意在命令行界面进行了一次查询,没有索引的时间显示为 ‘0.00 sec’ ,请问师兄这是数据过少的原因吗?(我这里面是30条数据)


收获:通过今天的学习,学到了索引的一些操作,以及索引的语法、sql语句。索引虽然可以提高MySQL检索的速度。在不同的情况下,创建索引是否合理。以及是否需要创建索引的情况。普及了一下hash索引方法和btree索引方法的确切知识。对比有无索引的前后对比,虽然结果好像有些问题。


明天继续学习后面的知识。




返回列表 返回列表
评论

    分享到