h5做的网站,wordpress悬浮音乐插件,山东网络公司排名,手表网站代码1、什么是索引#xff1f;
索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分)#xff0c;它们包含着对数据表里所有记录的引用指针。
索引是一种数据结构。数据库索引#xff0c;是数据库管理系统中一个排序的数据结构#xff0c;以协助快速查询、更新数…1、什么是索引
索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分)它们包含着对数据表里所有记录的引用指针。
索引是一种数据结构。数据库索引是数据库管理系统中一个排序的数据结构以协助快速查询、更新数据库表中数据。索引的实现通常使用B树及其变种B树。
更通俗的说索引就相当于目录。为了方便查找书中的内容通过对内容建立索引形成目录。索引是一个文件它是要占据物理空间的。
2、索引有哪些优缺点
索引的优点
1可以大大加快数据的检索速度这也是创建索引的最主要的原因。
2通过使用索引可以在查询的过程中使用优化隐藏器提高系统的性能。
索引的缺点
1时间方面创建索引和维护索引要耗费时间具体地当对表中的数据进行增加、删除和修改的时候索引也要动态的维护会降低增/改/删的执行效率
2空间方面索引需要占物理空间。
3、索引使用场景重点
where 上图中根据id查询记录因为id字段仅建立了主键索引因此此SQL执行可选的索引只有主键索引如果有多个最终会选一个较优的作为检索的依据。
– 增加一个没有建立索引的字段altertable innodb1 add sex char(1); – 按sex检索时可选的索引为nullEXPLAINSELECT*from innodb1 where sex‘男’; 可以尝试在一个字段未建立索引时根据该字段查询的效率然后对该字段建立索引alter table 表名 add index(字段名)同样的SQL执行的效率你会发现查询效率会有明显的提升数据量越大越明显。 order by
当我们使用order by将查询结果按照某个字段排序时如果该字段没有建立索引那么执行计划会将查询出的所有数据使用外部排序将数据从硬盘分批读取到内存使用内部排序最后合并排序结果这个操作是很影响性能的因为需要将查询涉及到的所有数据从磁盘中读到内存如果单条数据过大或者数据量过多都会降低效率更无论读到内存之后的排序了。
但是如果我们对该字段建立索引alter table 表名 add index(字段名)那么由于索引本身是有序的因此直接按照索引的顺序和映射关系逐条取出数据即可。而且如果分页的那么只用取出索引表某个范围内的索引对应的数据而不用像上述那取出所有数据进行排序再返回某个范围内的数据。从磁盘取数据是最影响性能的
join 对join语句匹配关系on涉及的字段建立索引能够提高效率 索引覆盖
如果要查询的字段都建立过索引那么引擎会直接在索引表中查询而不会访问原始数据否则只要有一个字段没有建立索引就会做全表扫描这叫索引覆盖。因此我们需要尽可能的在select后只写必要的查询字段以增加索引覆盖的几率。
这里值得注意的是不要想着为每个字段建立索引因为优先使用索引的优势就在于其体积小。
4、索引有哪几种类型
主键索引
数据列不允许重复不允许为NULL一个表只能有一个主键。
唯一索引
数据列不允许重复允许为NULL值一个表允许多个列创建唯一索引。
1可以通过 ALTER TABLE table_name ADD UNIQUE (column); 创建唯一索引
2可以通过 ALTER TABLE table_name ADD UNIQUE (column1,column2);创建唯一组合索引
普通索引
基本的索引类型没有唯一性的限制允许为NULL值。
1可以通过ALTER TABLE table_name ADD INDEX index_name (column);创建普通索引
2可以通过ALTER TABLE table_name ADD INDEX index_name(column1, column2, column3);创建组合索引
全文索引
是目前搜索引擎使用的一种关键技术。
可以通过ALTER TABLE table_name ADD FULLTEXT (column);创建全文索引
5、索引的数据结构b树hash
索引的数据结构和具体存储引擎的实现有关在MySQL中使用较多的索引有Hash索引B树索引等而我们经常使用的InnoDB存储引擎的默认索引实现为B树索引。对于哈希索引来说底层的数据结构就是哈希表因此在绝大多数需求为单条记录查询的时候可以选择哈希索引查询性能最快其余大部分场景建议选择BTree索引。
1B树索引
mysql通过存储引擎取数据基本上90%的人用的就是InnoDB了按照实现方式分InnoDB的索引类型目前只有两种BTREEB树索引和HASH索引。B树索引是Mysql数据库中使用最频繁的索引类型基本所有存储引擎都支持BTree索引。通常我们说的索引不出意外指的就是B树索引实际是用B树实现的因为在查看表索引时mysql一律打印BTREE所以简称为B树索引 查询方式
主键索引区:PI(关联保存的时数据的地址)按主键查询,
普通索引区:si(关联的id的地址,然后再到达上面的地址)。所以按主键查询,速度最快
Btree性质
1n棵子tree的节点包含n个关键字不用来保存数据而是保存数据的索引。
2所有的叶子结点中包含了全部关键字的信息及指向含这些关键字记录的指针且叶子结点本身依关键字的大小自小而大顺序链接。
3所有的非终端结点可以看成是索引部分结点中仅含其子树中的最大或最小关键字。
4B 树中数据对象的插入和删除仅在叶节点上进行。
5B树有2个头指针一个是树的根节点一个是最小关键码的叶节点。
2哈希索引
简要说下类似于数据结构中简单实现的HASH表散列表一样当我们在mysql中用哈希索引时主要就是通过Hash算法常见的Hash算法有直接定址法、平方取中法、折叠法、除数取余法、随机数法将数据库字段数据转换成定长的Hash值与这条数据的行指针一并存入Hash表的对应位置如果发生Hash碰撞两个不同关键字的Hash值相同则在对应Hash键下以链表形式存储。当然这只是简略模拟图。 6、索引的基本原理
索引用来快速地寻找那些具有特定值的记录。如果没有索引一般来说执行查询时遍历整张表。
索引的原理很简单就是把无序的数据变成有序的查询
1把创建了索引的列的内容进行排序
2对排序结果生成倒排表
3在倒排表内容上拼上数据地址链
4在查询的时候先拿到倒排表内容再取出数据地址链从而拿到具体数据
7、索引算法有哪些
索引算法有 BTree算法和Hash算法
BTree算法
BTree是最常用的mysql数据库索引算法也是mysql默认的算法。因为它不仅可以被用在,,,,和between这些比较操作符上而且还可以用于like操作符只要它的查询条件是一个不以通配符开头的常量 例如
– 只要它的查询条件是一个不以通配符开头的常量selectfromuserwhere name like’jack%’; – 如果一通配符开头或者没有使用常量则不会使用索引例如 selectfromuserwhere name like’%jack’;
Hash算法
Hash Hash索引只能用于对等比较例如,相当于操作符。由于是一次定位数据不像BTree索引需要从根节点到枝节点最后才能访问到页节点这样多次IO访问所以检索效率远高于BTree索引。
8、索引设计的原则
1适合索引的列是出现在where子句中的列或者连接子句中指定的列
2基数较小的类索引效果较差没有必要在此列建立索引
3使用短索引如果对长字符串列进行索引应该指定一个前缀长度这样能够节省大量索引空间
4不要过度索引。索引需要额外的磁盘空间并降低写操作的性能。在修改表内容的时候索引会进行更新甚至重构索引列越多这个时间就会越长。所以只保持需要的索引有利于查询即可。
9、创建索引的原则重中之重
索引虽好但也不是无限制的使用最好符合一下几个原则
1 最左前缀匹配原则组合索引非常重要的原则mysql会一直向右匹配直到遇到范围查询(、、between、like)就停止匹配比如a 1 and b 2 and c 3 and d 4 如果建立(a,b,c,d)顺序的索引d是用不到索引的如果建立(a,b,d,c)的索引则都可以用到a,b,d的顺序可以任意调整。
2较频繁作为查询条件的字段才去创建索引
3更新频繁字段不适合创建索引
4若是不能有效区分数据的列不适合做索引列(如性别男女未知最多也就三种区分度实在太低)
5尽量的扩展索引不要新建索引。比如表中已经有a的索引现在要加(a,b)的索引那么只需要修改原来的索引即可。
6定义有外键的数据列一定要建立索引。
7对于那些查询中很少涉及的列重复值比较多的列不要建立索引。
8对于定义为text、image和bit的数据类型的列不要建立索引。
10、创建索引的三种方式删除索引
第一种方式在执行CREATE TABLE时创建索引
CREATETABLE user_index2 (
第二种方式使用ALTER TABLE命令去增加索引
ALTERTABLE table_name ADDINDEX index_name (column_list); ALTER TABLE用来创建普通索引、UNIQUE索引或PRIMARY KEY索引。
其中table_name是要增加索引的表名column_list指出对哪些列进行索引多列时各列之间用逗号分隔。
索引名index_name可自己命名缺省时MySQL将根据第一个索引列赋一个名称。另外ALTER TABLE允许在单个语句中更改多个表因此可以在同时创建多个索引。
第三种方式使用CREATE INDEX命令创建
CREATEINDEX index_name ON table_name (column_list); CREATE INDEX可对表增加普通索引或UNIQUE索引。但是不能创建PRIMARY KEY索引
删除索引
根据索引名删除普通索引、唯一索引、全文索引
ALTER TABLE 表名 DROP KEY 索引名 altertable user_index dropKEY NAME; altertable user_index dropKEY id_card; altertable user_index dropKEY information; 删除主键索引alter table 表名 drop primary key因为主键只有一个。这里值得注意的是如果主键自增长那么不能直接执行此操作自增长依赖于主键索引
需要取消自增长再行删除
altertable user_index – 重新定义字段MODIFY id int,dropPRIMARYKEY 但通常不会删除主键因为设计主键一定与业务逻辑无关。
11、创建索引时需要注意什么
1非空字段
应该指定列为NOT NULL除非你想存储NULL。在mysql中含有空值的列很难进行查询优化因为它们使得索引、索引的统计信息以及比较运算更加复杂。你应该用0、一个特殊的值或者一个空串代替空值
2取值离散大的字段
变量各个取值之间的差异程度的列放到联合索引的前面可以通过count()函数查看字段的差异值返回值越大说明字段的唯一值越多字段的离散程度高
3索引字段越小越好
数据库的数据存储以页为单位一页存储的数据越多一次IO操作获取的数据越大效率越高。
12、使用索引查询一定能提高查询的性能吗为什么
通常通过索引查询数据比全表扫描要快。但是我们也必须注意到它的代价。
1索引需要空间来存储也需要定期维护 每当有记录在表中增减或索引列被修改时索引本身也会被修改。 这意味着每条记录的INSERTDELETEUPDATE将为此多付出45 次的磁盘I/O。 因为索引需要额外的存储空间和处理那些不必要的索引反而会使查询反应时间变慢。使用索引查询不一定能提高查询性能索引范围查询(INDEX RANGE SCAN)适用于两种情况:
2基于一个范围的检索一般查询返回结果集小于表中记录数的30%
3基于非唯一性索引的检索
13、百万级别或以上的数据如何删除
关于索引由于索引需要额外的维护成本因为索引文件是单独存在的文件,所以当我们对数据的增加,修改,删除,都会产生额外的对索引文件的操作,这些操作需要消耗额外的IO,会降低增/改/删的执行效率。所以在我们删除数据库百万级别数据的时候查询MySQL官方手册得知删除数据的速度和创建的索引数量是成正比的。
1所以我们想要删除百万数据的时候可以先删除索引此时大概耗时三分多钟
2然后删除其中无用数据此过程需要不到两分钟
3删除完成后重新创建索引(此时数据较少了)创建索引也非常快约十分钟左右。
4与之前的直接删除绝对是要快速很多更别说万一删除中断,一切删除会回滚。那更是坑了。
14、前缀索引
语法index(field(10))使用字段值的前10个字符建立索引默认是使用字段的全部内容建立索引。
前提前缀的标识度高。比如密码就适合建立前缀索引因为密码几乎各不相同。
实操的难度在于前缀截取的长度。
我们可以利用select count(*)/count(distinct left(password,prefixLen));通过从调整prefixLen的值从1自增查看不同前缀长度的一个平均匹配度接近1时就可以了表示一个密码的前prefixLen个字符几乎能确定唯一一条记录
15、什么是最左前缀原则什么是最左匹配原则
1顾名思义就是最左优先在创建多列索引时要根据业务需求where子句中使用最频繁的一列放在最左边。
2最左前缀匹配原则非常重要的原则mysql会一直向右匹配直到遇到范围查询(、、between、like)就停止匹配比如a 1 and b 2 and c 3 and d 4 如果建立(a,b,c,d)顺序的索引d是用不到索引的如果建立(a,b,d,c)的索引则都可以用到a,b,d的顺序可以任意调整。
3和in可以乱序比如a 1 and b 2 and c 3 建立(a,b,c)索引可以任意顺序mysql的查询优化器会帮你优化成索引可以识别的形式
16、B树和B树的区别
1在B树中你可以将键和值存放在内部节点和叶子节点但在B树中内部节点都是键没有值叶子节点同时存放键和值。
2B树的叶子节点有一条链相连而B树的叶子节点各自独立。 17、使用B树的好处
B树可以在内部节点同时存储键和值因此把频繁访问的数据放在靠近根节点的地方将会大大提高热点数据的查询效率。这种特性使得B树在特定数据重复多次查询的场景中更加高效。
18、使用B树的好处
由于B树的内部节点只存放键不存放值因此一次读取可以在内存页中获取更多的键有利于更快地缩小查找范围。 B树的叶节点由一条链相连因此当需要进行一次全数据遍历的时候B树只需要使用O(logN)时间找到最小的一个节点然后通过链进行O(N)的顺序遍历即可。而B树则需要对树的每一层进行遍历这会需要更多的内存置换次数因此也就需要花费更多的时间
19、Hash索引和B树所有有什么区别或者说优劣呢?
首先要知道Hash索引和B树索引的底层实现原理
hash索引底层就是hash表进行查找时调用一次hash函数就可以获取到相应的键值之后进行回表查询获得实际数据。B树底层实现是多路平衡查找树。对于每一次的查询都是从根节点出发查找到叶子节点方可以获得所查键值然后根据查询判断是否需要回表查询数据。
那么可以看出他们有以下的不同
hash索引进行等值查询更快(一般情况下)但是却无法进行范围查询。
因为在hash索引中经过hash函数建立索引之后索引的顺序与原顺序无法保持一致不能支持范围查询。而B树的的所有节点皆遵循(左节点小于父节点右节点大于父节点多叉树也类似)天然支持范围。
hash索引不支持使用索引进行排序原理同上。hash索引不支持模糊查询以及多列索引的最左前缀匹配。原理也是因为hash函数的不可预测。AAAA和AAAAB的索引没有相关性。hash索引任何时候都避免不了回表查询数据而B树在符合某些条件(聚簇索引覆盖索引等)的时候可以只通过索引完成查询。hash索引虽然在等值查询上较快但是不稳定。性能不可预测当某个键值存在大量重复的时候发生hash碰撞此时效率可能极差。而B树的查询效率比较稳定对于所有的查询都是从根节点到叶子节点且树的高度较低。
因此在大多数情况下直接选择B树索引可以获得稳定且较好的查询速度。而不需要使用hash索引。
20、数据库为什么使用B树而不是B树
1B树只适合随机检索而B树同时支持随机检索和顺序检索
2B树空间利用率更高可减少I/O次数磁盘读写代价更低。一般来说索引本身也很大不可能全部存储在内存中因此索引往往以索引文件的形式存储的磁盘上。这样的话索引查找过程中就要产生磁盘I/O消耗。B树的内部结点并没有指向关键字具体信息的指针只是作为索引使用其内部结点比B树小盘块能容纳的结点中关键字数量更多一次性读入内存中可以查找的关键字也就越多相对的IO读写次数也就降低了。而IO读写次数是影响索引检索效率的最大因素
3B树的查询效率更加稳定。B树搜索有可能会在非叶子结点结束越靠近根节点的记录查找时间越短只要找到关键字即可确定记录的存在其性能等价于在关键字全集内做一次二分查找。而在B树中顺序检索比较明显随机检索时任何关键字的查找都必须走一条从根节点到叶节点的路所有关键字的查找路径长度相同导致每一个关键字的查询效率相当。
4B-树在提高了磁盘IO性能的同时并没有解决元素遍历的效率低下的问题。B树的叶子节点使用指针顺序连接在一起只要遍历叶子节点就可以实现整棵树的遍历。而且在数据库中基于范围的查询是非常频繁的而B树不支持这样的操作。
5增删文件节点时效率更高。因为B树的叶子节点包含所有关键字并以有序的链表结构存储这样可很好提高增删效率。
21、B树在满足聚簇索引和覆盖索引的时候不需要回表查询数据
在B树的索引中叶子节点可能存储了当前的key值也可能存储了当前的key值以及整行的数据这就是聚簇索引和非聚簇索引。 在InnoDB中只有主键索引是聚簇索引如果没有主键则挑选一个唯一键建立聚簇索引。如果没有唯一键则隐式的生成一个键来建立聚簇索引。
当查询使用聚簇索引时在对应的叶子节点可以获取到整行数据因此不用再次进行回表查询。
22、什么是聚簇索引何时使用聚簇索引与非聚簇索引
1聚簇索引将数据存储与索引放到了一块找到索引也就找到了数据
2非聚簇索引将数据存储于索引分开结构索引结构的叶子节点指向了数据的对应行myisam通过key_buffer把索引先缓存到内存中当需要访问数据时通过索引访问数据在内存中直接搜索索引然后通过索引找到磁盘相应数据这也就是为什么索引不在key buffer命中时速度慢的原因
澄清一个概念innodb中在聚簇索引之上创建的索引称之为辅助索引辅助索引访问数据总是需要二次查找非聚簇索引都是辅助索引像复合索引、前缀索引、唯一索引辅助索引叶子节点存储的不再是行的物理位置而是主键值
何时使用聚簇索引与非聚簇索引 23、非聚簇索引一定会回表查询吗
不一定这涉及到查询语句所要求的字段是否全部命中了索引如果全部命中了索引那么就不必再进行回表查询。
举个简单的例子假设我们在员工表的年龄上建立了索引那么当进行select age from employee where age 20的查询时在索引的叶子节点上已经包含了age信息不会再次进行回表查询。
24、联合索引是什么为什么需要注意联合索引中的顺序
MySQL可以使用多个字段同时建立一个索引叫做联合索引。在联合索引中如果想要命中索引需要按照建立索引时的字段顺序挨个使用否则无法命中索引。
具体原因为:
MySQL使用索引时需要索引有序假设现在建立了nameageschool的联合索引那么索引的排序为: 先按照name排序如果name相同则按照age排序如果age的值也相等则按照school进行排序。
当进行查询时此时索引仅仅按照name严格有序因此必须首先使用name字段进行等值查询之后对于匹配到的列而言其按照age字段严格有序此时可以使用age字段用做索引查找以此类推。因此在建立联合索引的时候应该注意索引列的顺序一般情况下将查询需求频繁或者字段选择性高的列放在前面。此外可以根据特例的查询或者表结构进行单独的调整。