参考:
四种mysql存储引擎
MySQL(五) MySQL中的索引详讲
一、什么是索引?为什么要建立索引?
Mysql中的索引的存储类型有两种:B树索引、Hash索引
优点:大大加快数据的查询速度,不需要在表中顺序遍历;
为什么有了索引就会加快查询速度呢?
有了索引,可以根据索引快速到达一个一个位置去搜索文件,而不必查看所有的数据;没有索引的话,需要根据表中记录顺序遍历,直到找到这条记录;
缺点:
创建索引和维护索引要耗费时间,并且随着数据量的增加所耗费的时间也会增加;
索引也需要占空间;
当对表中的数据进行增加、删除、修改时,索引也需要动态的维护,降低了数据的维护速度;
二、何时使用索引呢?
总结:经常查询的表建立索引;频繁更新的表不要建立过多索引;数据量比较小的表不要建立索引;对于列值较少的不要建立索引,对于列值较多的建立索引;
并不是每个字段度设置索引就好,也不是索引越多越好,而是需要自己合理的使用。
1、对经常更新的表就避免对其进行过多的索引,对经常用于查询的字段应该创建索引,
2、数据量小的表最好不要使用索引,因为由于数据较少,可能查询全部数据花费的时间比遍历索引的时间还要短,索引就可能不会产生优化效果。
3、在一同值少的列上(字段上)不要建立索引,比如在学生表的"性别"字段上只有男,女两个不同值。相反的,在一个字段上不同值较多可是建立索引。
在索引优化时:选择利用最左前缀原则;
使用短索引;
不要过度索引,只保持所需的索引;
三、Mysql的存储引擎有哪些?
参考:四种mysql存储引擎
Mysql的常见存储引擎有四个:MylSAM、InnoDB、MEMORY、Merge
1)MylSAM:
是MySql使用的是表级锁;拥有较高的插入、查询速度,因此适合筛选大量数据;但不支持事务,也不支持外键;支持全文索引,最大的缺陷是崩溃后无法安全恢复。
使用MyISAM引擎创建数据库,将产生3个文件,文件的名字以表名字开始,扩展名是文件类型:例如创建了boy_demo表
- boy_demo.frm 存储表定义;
- boy_demo.MYD 存储数据;
- boy_demo.MYI 存储索引;
使用场景:适合筛选大量数据,读性能稳定,高可用。
备注:Mysql在V5.1之前默认存储引擎是MyISAM;在此之后默认存储引擎是InnoDB
2)InnoDB
InnoDB是事务型数据库的首选引擎,支持事务安全表(ACID),支持行锁定和外键,InnoDB是默认的MySQL引擎;(5.6加入了全文检索)
具有事务的特性,与ACID兼容;
适合更新密集的表,处理多重并发的更新请求;
支持外键的约束;
支持自动增加列ATUO_INCREMENT属性;
使用场景:支持事务和外键约束,可处理高并发请求
3)memery
数据是放在内存中的,并且默认使用HASH/Tree索引
特点:
速度快,响应时间短
使用场景:目标数据较小,且被频繁访问,临时数据可放于内存表中,内存表中数据即使丢失也不会有太大影响。
4) Archive存储引擎
Archive存储引擎置只支持INSERT和SELECT操作,支持行锁,但本身并不是事务安全的存储引擎,其最大的优点是其具有较好的压缩比,压缩比一般可达到1:10,可以将同样的数据以更小的磁盘空间占用来存储。
Archive存储引擎非常适合存储归档数据,如历史数据、日志信息数据等等,这类数据往往数据量非常大,并且基本只有INSERT和SELECT操作,使用这个存储引擎可以非常节约磁盘空间。
5)Merge
Merge存储引擎是一组MyISAM表的组合,这些MyISAM表必须结构完全相同,merge表本身并没有数据,对merge类型的表可以进行查询,更新,删除操作,这些操作实际上是对内部的MyISAM表进行的。
总结:
插入和查询,适合筛选大量数据;---MyISAM
事务和并发---InnoDB
临时表、中间结果---Memory
高并发插入查询,归档数据---Archive
如果要提供提交、回滚、崩溃恢复能力的事务安全(ACID兼容)能力,并要求实现并发控制,InnoDB是一个好的选择
如果数据表主要用来插入和查询记录,则MyISAM引擎能提供较高的处理效率
如果只是临时存放数据,数据量不大,并且不需要较高的数据安全性,可以选择将数据保存在内存中的Memory引擎,MySQL中使用该引擎作为临时表,存放查询的中间结果
如果只有INSERT和SELECT操作,可以选择Archive,Archive支持高并发的插入操作,但是本身不是事务安全的。Archive非常适合存储归档数据,如记录日志信息可以使用Archive
四、Mysql实现索引有哪些数据结构呢?索引有哪些分类呢?
Mysql索引主要有两种结构:B+Tree索引和Hash索引
索引是在存储引擎中实现的,也就是说不同的存储引擎,会使用不同的索引
MyISAM和InnoDB存储引擎:只支持B树索引, 也就是说默认使用B树,不能够更换
MEMORY/HEAP存储引擎:支持Hash和B树索引
索引的分类:
Mysql常见索引有:主键索引、唯一索引、普通索引、全文索引、组合索引
Mysql各种索引区别:
普通索引:最基本的索引,没有任何限制
唯一索引:与"普通索引"类似,不同的就是:索引列的值必须唯一,但允许有空值。
主键索引:它是一种特殊的唯一索引,不允许有空值。
全文索引:仅可用于 MyISAM 表,针对较大的数据,生成全文索引很耗费时间和空间。
组合索引:为了更多的提高mysql效率可建立组合索引,遵循”最左前缀“原则。创建复合索引时应该将最常用(频率)作限制条件的列放在最左边,依次递减。组合索引要不全用要不都不要用
PRIMARY KEY(主键索引) ALTER TABLE
table_name
ADD PRIMARY KEY (col
)
UNIQUE(唯一索引) ALTER TABLEtable_name
ADD UNIQUE (col
)
INDEX(普通索引) ALTER TABLEtable_name
ADD INDEX index_name (col
)
FULLTEXT(全文索引) ALTER TABLEtable_name
ADD FULLTEXT (col
)
组合索引 ALTER TABLEtable_name
ADD INDEX index_name (col1
,col2
,col3
)
五、如何选择索引的数据类型?
总结:数据类型小、简单,减少存储空间和处理效率;避免Null值;
MySQL支持很多数据类型,选择合适的数据类型存储数据对性能有很大的影响。通常来说,可以遵循以下一些指导原则:
(1)越小的数据类型通常更好:越小的数据类型通常在磁盘、内存和CPU缓存中都需要更少的空间,处理起来更快。
(2)简单的数据类型更好:整型数据比起字符,处理开销更小,因为字符串的比较更复杂。在MySQL中,应该用内置的日期和时间数据类型,而不是用字符串来存储时间;以及用整型数据类型存储IP地址。
(3)尽量避免NULL:应该指定列为NOT NULL,除非你想存储NULL。在MySQL中,含有空值的列很难进行查询优化,因为它们使得索引、索引的统计信息以及比较运算更加复杂。你应该用0、一个特殊的值或者一个空串代替空值。
六、聚簇索引和非聚簇索引是什么呢?/
聚簇索引:
聚簇索引的数据的物理存放顺序与索引顺序是一致的,即:只要索引是相邻的,那么对应的数据一定也是相邻地存放在磁盘上的。聚簇索引要比非聚簇索引查询效率高很多。
聚集索引这种主+辅索引的好处是,当发生数据行移动或者页分裂时,辅助索引树不需要更新,因为辅助索引树存储的是主索引的主键关键字,而不是数据具体的物理地址。
非聚集索引:
记录的物理顺序与逻辑顺序没有必然的联系,与数据的存储物理结构没有关系;一个表对应的非聚簇索引可以有多条,根据不同列的约束可以建立不同要求的非聚簇索引;非聚集索引,类似于图书的附录,那个专业术语出现在哪个章节,这些专业术语是有顺序的,但是出现的位置是没有顺序的。
每个表只能有一个聚簇索引,因为一个表中的记录只能以一种物理顺序存放。但是,一个表可以有不止一个非聚簇索引。
InnoDB使用的是聚簇索引,叶子节点上的data是主键(所以聚簇索引的key,不能过长);将主键组织到一棵B+树中,而行数据就储存在叶子节点上,若使用"where id = 14"这样的条件查找主键,则按照B+树的检索算法即可查找到对应的叶节点,之后获得行数据。若对Name列进行条件搜索,则需要两个步骤:第一步在辅助索引B+树中检索Name,到达其叶子节点获取对应的主键。第二步使用主键在主索引B+树种再执行一次B+树检索操作,最终到达叶子节点即可获取整行数据。
MyISAM的是非聚簇索引,B+Tree的叶子节点上的data,并不是数据本身,而是数据存放的地址。主索引和辅助索引没啥区别,只是主索引中的key一定得是唯一的。
七、MySQL存放IP地址 用数值型有什么好处?
参考:
MySQL存放IP地址 用数值型有什么好处?
论IP地址在数据库中应该用何种形式存储
总结:使用unsigned int的整数类型的,查询效率高且存储空间较合理;
如果选择字符类型的,可读性好但是占存储空间
很多程序员都会创建一个 VARCHAR(15) 字段来存放字符串形式的IP而不是整形的IP。如果用整形来存放,只需要4个字节,并且可以有定长的字段。会带来查询上的优势,尤其是使用WHERE条件:IP between ip1 and ip2时;
我们必需要使用UNSIGNED INT(unsigned int),因为 IP地址会使用整个32位的无符号整形。
八、什么时候会索引失效呢?
1、对单字段建了索引,where条件多字段。
2、建立联合索引,where条件单字段。没有符合左前缀匹配选择,也索引失效
3、对索引列运算,运算包括(+、-、*、/、!、<>、%、like'%_'(%放在前面)、or、in、exist等),导致索引失效。
4、类型错误,如字段类型为varchar,where条件用number。(字符类型的应该加上引号,否则失效)
5、对索引应用内部函数,这种情况下应该建立基于函数的索引。(子查询使用了内部函数,则索引失效)
6、如果mysql估计使用全表扫描要比使用索引快,则不使用索引Linux
九、mysql建立索引的几大原则?
1.选择唯一性索引
2.为经常需要排序、分组和联合操作的字段建立索引
3.为常作为查询条件的字段建立索引
4.限制索引的数目
5.尽量使用数据量少的索引
6.尽量使用前缀来索引
7.删除不再使用或者很少使用的索引
8 . 最左前缀匹配原则,非常重要的原则。
9 .=和in可以乱序。
10 . 尽量选择区分度高的列作为索引。
11 .索引列不能参与计算,保持列“干净”。
12 .尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可