在MySQL中,创建索引的方法有两种:使用命令行工具或者使用MySQL图形化工具。以下是两种方法的详细步骤:
方法一:使用命令行工具
1. 登录到MySQL服务器。在命令行中输入以下命令:
```css
mysql -u 用户名 -p
```
其中,用户名是您的MySQL用户名。执行此命令后,系统将提示您输入密码。
2. 选择要创建索引的数据库。使用以下命令选择要创建索引的数据库:
```perl
use 数据库名;
```
其中,数据库名是您要创建索引的数据库名称。
3. 创建索引。使用以下命令创建索引:
```sql
ALTER TABLE 表名 ADD INDEX 索引名 (列名);
```
其中,表名是要添加索引的表名称,索引名是您为索引指定的名称,列名是要添加索引的列名称。
例如,如果您要在名为"users"的表的"email"列上创建一个名为"idx_email"的索引,可以使用以下命令:
```sql
ALTER TABLE users ADD INDEX idx_email (email);
```
方法二:使用MySQL图形化工具
1. 启动MySQL图形化工具(如phpMyAdmin或MySQL Workbench)。
2. 连接到您的MySQL服务器。输入服务器地址、用户名和密码。
3. 选择要创建索引的数据库和表。在图形化工具中,您可以通过单击数据库名称来选择它,然后选择您要创建索引的表。
4. 创建索引。在工具栏或右键菜单中,选择"Alter Table"(更改表)选项。在弹出的对话框中,选择要添加索引的列,并设置索引名称和其他选项。单击"Apply"(应用)按钮以创建索引。
5. 等待图形化工具完成操作。在操作完成后,您可以验证索引是否成功创建。您可以通过执行以下查询来检查是否已成功创建索引:
```sql
SHOW INDEX FROM 表名;
```
其中,表名是您要检查索引的表名称。
索引的顺序要遵循三个规则
1.要遵循最左前缀 无论是多个还是一个列的索引 都不应该跳过最左列 如果在查询语句当中 没有使用最左前缀的字段 就不会使用索引
2.不能跨越索引列
3.索引进行模糊查询 范围查询 ,右边的所有列都无法使用索引优化
MySQL建立索引最简单的目的就是对数据库的访问会快一点。一个表,如果没有索引,数据量少点的时候你不会觉得数据库本身的的性能问题,但是随着数据量的显著增加,比如超过一万条记录之后,可能你就会遇到数据库操作的性能问题了,这个时候,你建立索引就会显著的改善数据库的写入性能。
索引查询失效的几个情况:
1、like 以%开头,索引无效;当like前缀没有%,后缀有%时,索引有效。
2、or语句前后没有同时使用索引。当or左右查询字段只有一个是索引,该索引失效,只有当or左右查询字段均为索引时,才会生效。
3、组合索引,不是使用第一列索引,索引失效。
4、数据类型出现隐式转化。如varchar不加单引号的话可能会自动转换为int型,使索引无效,产生全表扫描。
5、在索引列上使用 IS NULL 或 IS NOT NULL操作。索引是不索引空值的,所以这样的操作不能使用索引,可以用其他的办法处理。
一、定义
索引定义:索引(Index)是帮助MySQL高效获取数据的数据结构。本质:索引是数据结构。
二、B-Tree
m阶B-Tree满足以下条件:1、每个节点至多可以拥有m棵子树。2、根节点,只有至少有2个节点(要么极端情况,就是一棵树就一个根节点,单细胞生物,即是根,也是叶,也是树)。3、非根非叶的节点至少有的Ceil(m/2)个子树(Ceil表示向上取整,如5阶B树,每个节点至少有3个子树,也就是至少有3个叉)。4、非叶节点中的信息包括[n,A0,K1,A1,K2,A2,…,Kn,An],,其中n表示该节点中保存的关键字个数,K为关键字且Ki<Ki+1,A为指向子树根节点的指针。5、从根到叶子的每一条路径都有相同的长度(叶子节点在相同的层)
B-Tree特性:
1、关键字集合分布在整颗树中;2、任何一个关键字出现且只出现在一个节点中;3、每个节点存储date和key;4、搜索有可能在非叶子节点结束;5、一个节点中的key从左到右非递减排列;6、所有叶节点具有相同的深度,等于树高h。
B-Tree上查找算法的伪代码如下:
三、B+Tree
B+Tree与B-Tree的差异在于:1、B+Tree非叶子节点不存储data,只存储key;2、所有的关键字全部存储在叶子节点上;3、每个叶子节点含有一个指向相邻叶子节点的指针,带顺序访问指针的B+树提高了区间查找能力;4、非叶子节点可以看成索引部分,节点中仅含有其子树(根节点)中的最大(或最小)关键字;
四、B/B+树索引的性能分析
依据:使用磁盘I/O次数评价索引结构的优劣主存和磁盘以页为单位交换数据,将一个节点的大小设为等于一个页,因此每个节点只需一次I/O就可以完全载入。根据B树的定义,可知检索一次最多需要访问h个节点渐进复杂度:O(h)=O(logdN) dmax=floor(pagesize/(keysize+datasize+pointsize))一般实际应用中,出度d是非常大的数字,通常超过100,因此h非常小(通常不超过3,3层可存大约一百万数据)B-Tree中一次检索最多需要h-1次I/O(根节点常驻内存)B+Tree内节点不含data域,因此出度d更大,则h更小,I/O次数少,效率更高,故B+Tree更适合外存索引。
五、MySQL索引实现1、MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址; MyISAM主索引和辅助索引在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复;
2、InnoDB的数据文件本身就是索引文件,叶节点包含了完整的数据记录,这种索引叫做聚集索引。因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键。 InnoDB的辅助索引data域存储相应记录主键的值而不是地址; 辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录;
3、页分裂问题
如果主键是单调递增的,每条新记录会顺序插入到页,当页被插满后,继续插入到新的页;
如果写入是乱序的,InnoDB不得不频繁地做页分裂操作,以便为新的行分配空间。页分裂会导致移动大量数据,一次插入最少需要修改三个页而不是一个页。
如果频繁的页分裂,页会变得稀疏并被不规则地填充,所以最终数据会有碎片。
六、总结
了解不同存储引擎的索引实现方式对于正确使用和优化索引都非常有帮助
1、为什么不建议使用过长的字段作为主键?
2、为什么选择自增字段作为主键?
3、为什么常更新是字段不建议建立索引?
4、为什么选择区分度高的列作为索引?区分度的公式是count(distinct col)/count(*)
5、尽可能的使用覆盖索引
七、优化LIMIT分页查询
SELECT * FROM table where condition LIMIT offset , rows ;上述SQL语句的实现机制是: 1、从“table”表中读取offset+rows行记录。 2、 抛弃前面的offset行记录,返回后面的rows行记录作为最终的结果。覆盖索引:select a.id, sid, parent_s_id from cashpool_account_relationship a join (select id from cashpool_account_relationship LIMIT 1000000,10)b on a.id = b.id;select id, sid, parent_s_id from cashpool_account_relationship where id >=(select id from cashpool_account_relationship LIMIT 1000000,1) LIMIT 10;
八、Q&A
1、InnoDB支持hash索引吗?--马欣InnoDB是支持hash索引的,不过其支持的hash索引是自适应的,InnoDB存储引擎会根据表的使用情况自动为表生成hash索引,不能人为干预是否在一张表中生成hash索引。2、InnoDB主键索引的叶节点含完整的数据记录,那主键索引文件要比数据文件大吗?--徐财厚1).在Innodb 引擎中,主键索引中的叶子结点包含记录数据,主键索引文件即为数据文件。2).在 tables 表中统计的data_length数据为主键索引大小,index_length 为统计的这个表中所有辅助索引(二级索引)索引的大小。
mysql建立索引是立即生效的,语句生效后索引也就建立成功了,可以建立索引进行快速的查询和检索
Hash索引:将索引字段转化为hashcode,在对hashcode进行排序。仅支持Memory引擎。
1. 普通索引:最基本的索引,它没有任何限制,用于加速查询。
2. 唯一索引unique:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。
3. 主键索引: 是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。一般是在建表的时候同时创建主键索引。
4. 空间索引Spatial :空间索引是对空间数据类型的字段建立的索引,MYSQL中的空间数据类型有4种,分别是GEOMETRY、POINT、LINESTRING、POLYGON。MYSQL使用SPATIAL关键字进行扩展,使得能够用于创建正规索引类型的语法创建空间索引。创建空间索引的列,必须将其声明为NOT NULL,空间索引只能在存储引擎为MYISAM的表中创建
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.= 和 in 可以乱序, 比如 a=1 and b=2 and c=3 建立(a,b,c)索引可以任意顺序, mysql 的查询优化器会帮你优化成索引可以识别的形式.
mysql索引有:
1、主键索引:主键索引是一种特殊的唯一索引,不允许有空值
2、普通索引或者单列索引
3、多列索引(复合索引):复合索引指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。使用复合索引时遵循最左前缀集合
4、唯一索引或者非唯一索引
5、空间索引:空间索引是对空间数据类型的字段建立的索引。MYSQL使用SPATIAL关键字进行扩展,使得能够用于创建正规索引类型的语法创建空间索引。
索引可以加快数据检索操作,但会使数据修改操作变慢。每修改数据记录,索引就必须刷新一次。为了在某种程度上弥补这一缺陷,许多SQL命令都有一个DELAY_KEY_WRITE项。
这个选项的作用是暂时制止MySQL在该命令每插入一条新记录和每修改一条现有之后立刻对索引进行刷新,对索引的刷新将等到全部记录插入/修改完毕之后再进行。在需要把许多新记录插入某个数据表的场合,DELAY_KEY_WRITE选项的作用将非常明显。