MySQL索引学习

听同事提起索引,只知道是一种类似树的结构,可以大幅提高查询效率,但是具体原理却不懂,所以搜索资料学习一下。

一、索引分类

1.主键索引:根据主键pk_clolum(length)建立索引,不允许重复,不允许空值

ALTER TABLE 'table_name' ADD PRIMARY KEY pk_index('col');

2.唯一索引:用来建立索引的列的值必须是唯一的,允许空值

ALTER TABLE 'table_name' ADD UNIQUE index_name('col');

3.普通索引:用表中的普通列构建的索引,没有任何限制

ALTER TABLE 'table_name' ADD INDEX index_name('col');

4.全文索引:用大文本对象的列构建的索引

ALTER TABLE 'table_name' ADD FULLTEXT INDEX ft_index('col');

5.组合索引:用多个列组合构建的索引,这多个列中的值不允许有空值

-- 遵循“最左前缀”原则,把最常用作为检索或排序的列放在最左,依次递减,
-- 组合索引相当于建立了col1,col1col2,col1col2col3三个索引
-- 而col2或者col3是不能使用索引的。
ALTER TABLE 'table_name' ADD INDEX index_name('col1','col2','col3');

如果组合索引列,列名比较长,可以采用截取的方式:

ALTER TABLE 'table_name' ADD INDEX index_name(col1(4),col2(3));

二、索引原理

MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,B+Tree索引,哈希索引,全文索引等等

1、哈希索引:

只在memory(内存)存储引擎支持,哈希索引使用散列算法,因此访问速度非常快,但是一个值只能对应一个hashCode,而且是散列的分布方式,因此哈希索引不支持范围查找和排序的功能。

2、全文索引:

FULLTEXT(全文)索引,只能用于MyISAM 和 InnoDB(5.6版本之后)。

具体参考:全文索引的深入理解

-- 1.创建表的时候添加FULLTEXT索引
CTREATE TABLE my_table(
    id INT(10) PRIMARY KEY,
    name VARCHAR(10) NOT NULL,
    my_text TEXT,
    FULLTEXT(my_text)
)ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- 2.创建表以后,在需要的时候添加FULLTEXT索引
ALTER TABLE my_table ADD FULLTEXT INDEX ft_index(column_name);

-- 3.查询方式
SELECT * FROM table_name MATCH(ft_index) AGAINST('查询字符串');

3、B-Tree索引

BTree又叫平衡多路查找树,一棵m(即任何一个节点中元素的数量<m)阶的B 树 (m叉树)的特性如下:

  • 每个叶子结点的高度一样;
  • 树中每个结点最多含有m-1个孩子(m>=2);
  • 除根结点和叶子结点外,其它每个结点至少有[ceil(m / 2)]个孩子(其中ceil(x)是一个取上限的函数);
  • 若根结点不是叶子结点,则至少有2个孩子(特殊情况:没有孩子的根结点,即根结点为叶子结点,整棵树只有一个根节点);

  • 所有叶子结点都出现在同一层,叶子结点不包含任何关键字信息(可以看做是外部接点或查询失败的接点,实际上这些结点不存在,指向这些结点的指针都为null);

  • 每个非终端结点中包含有n个关键字信息: (P1,K1,P2,K2,P3,......,Kn,Pn+1)。其中:
           a)   Ki (i=1...n)为关键字,且关键字按顺序升序排序K(i-1)< Ki。 
           b)   Pi为指向子树根的接点,且指针P(i)指向子树种所有结点的关键字均小于Ki,但都大于K(i-1)。 
           c)   关键字的个数n必须满足: [ceil(m / 2)-1]<= n <= m-1(这个特别重要,记住了)

详情参考:BTree深入学习

以下是我学习这篇博客的总结:

1.添加元素时,无非是满了就分裂(将一个中间元素送给父节点)

2.删除时需要考虑的比较多,但是需要遵循几个原则:

  1. 叶节点元素删除完之后,依然满足要求,只需正常删除,然后把该元素后边的元素迁移即可;
  2. 非叶节点删除,删除元素时,需要将该节点下边子节点的对应元素挪上来补上空缺,因为我们要维护父节点到子节点的指针。
  3. 叶节点删除时,先借用相邻丰满节点数据(从父节点借数据,然后将相邻节点数据补给父节点);
  4. 如果叶节点不满足条件三,走该逻辑。两个节点合并。
    1. 向父节点借一个元素,补给缺少数据的节点
    2. 将该节点和相邻节点合并,并将父节点的指针指向合并后的节点。

三、索引优缺点

优势:可以快速检索,减少I/O次数,加快检索速度;根据索引分组和排序,可以加快分组和排序;

劣势:索引本身也是表,因此会占用存储空间,一般来说,索引表占用的空间的数据表的1.5倍;索引表的维护和创建需要时间成本,这个成本随着数据量增大而增大;构建索引会降低数据表的修改操作(删除,添加,修改)的效率,因为在修改数据表的同时还需要修改索引表;

 

### 学习 MySQL 素引的基础知识 学习 MySQL索引涉及多个方面,包括理解其基本概念、创建方法以及最佳实践。以下是关于这些主题的详细介绍。 #### 基本概念 MySQL 中的索引是一种用于加速数据检索的技术结构。通过在表中建立索引,可以显著减少查询时间,尤其是在大数据量的情况下。然而,过多或不当使用的索引可能会增加写操作的时间开销[^1]。 #### 如何创建索引 可以通过 `CREATE INDEX` 或者修改表定义的方式创建索引。例如: ```sql -- 单列索引 CREATE INDEX idx_name ON table_name(column_name); -- 组合索引 CREATE INDEX combined_idx ON table_name(col1, col2); ``` 需要注意的是,在组合索引 `(col1, col2)` 中,如果仅针对第二列进行过滤 (`WHERE col2 = ...`) 而不包含第一列,则该索引可能不会被有效利用[^4]。 #### 使用场景分析 了解何时应该使用索引非常重要。对于某些复杂的 SQL 查询,比如带有子查询或者多表连接的情况,即使存在可用的索引也可能由于成本估算的原因而未被采用。例如,当 `IN` 条件中的值数量较多时,优化器可能会决定放弃索引转而执行全表扫描[^3]。 另外,在涉及到逻辑运算符如 `AND` 时需注意,尽管各个参与比较的字段都单独建立了索引,但实际运行过程中数据库引擎通常会选择其中一个作为访问路径,其余部分则依赖回表完成进一步筛选[^5]。 #### 性能调优技巧 为了最大化发挥索引的作用,可以从以下几个角度入手: - **定期审查慢日志**:找出那些消耗资源较大的SQL语句,并针对性地调整它们所关联的对象上的索引设置; - **避免不必要的排序动作**(`USING FILESORT`):尽量让查询能够直接按照现有索引顺序返回结果集,从而规避额外产生的磁盘I/O负担[^2]; - **合理设计复合键**:考虑到覆盖率等因素精心挑选构成联合索引的各项属性; 最后提醒一点就是随着业务发展不断变化的需求可能导致原先规划良好的方案变得不再适用,因此持续监控系统表现并适时作出相应改动是非常必要的。 ### 实践案例分享 假设有一个员工信息管理系统的场景下需要频繁查找特定姓名范围内的记录数统计情况,那么除了简单地给名字这一维度加常规B树形式外还可以考虑尝试全文搜索引擎插件或者其他更高级别的解决方案来满足更加苛刻的要求。 ```sql SELECT COUNT(*) AS count_result FROM employees WHERE MATCH(first_name,last_name) AGAINST('John Smith'); ``` 上述例子展示了如何借助MyISAM存储引擎特有的功能实现模糊匹配的同时保持较高的效率水平。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值