MySQL中为什么要使用索引合并(Index Merge)?

mysql,index,merge · 浏览次数 : 64

小编点评

本文详细介绍了MySQL中索引合并(Index Merge)的概念、实现原理、适用场景以及优缺点。索引合并是一种优化手段,可以在多个索引上进行条件扫描,将满足条件的多个主键集合取交集或并集后再进行回表,从而提高查询效率。 1. **索引合并介绍**: - 索引合并是MySQL 5.x版本引入的一种优化手段,用于解决单个索引上无法满足复杂查询条件的问题。 - 它能够在多个索引上同时进行条件扫描,并将满足条件的多个主键集合取交集或并集后再进行回表。 2. **索引合并类型**: - **交集(intersection)**:取多个索引扫描结果的交集。 - **并集(union)**:取多个索引扫描结果的并集。 - **排序并集(sort-union)**:先对索引扫描结果进行排序,然后取并集。 3. **实现原理**: - 索引合并的实现涉及到索引扫描、记录比较和记录排序等步骤。 - 在每个索引扫描阶段,MySQL会根据搜索条件获取相应的主键id集合。 - 然后,根据不同的合并策略(交集、并集或排序并集),将这些主键id集合取交集、并集或排序后进行回表查询。 4. **适用场景**: - 索引合并适用于查询条件列较多且无法使用联合索引的情况。 - 当查询条件涉及多个索引的交集或并集时,使用索引合并可以提高查询效率。 5. **优缺点**: - **优点**:能够减少随机IO次数,提高查询效率。 - **缺点**:在某些情况下,如查询条件涉及大量重复值时,索引合并可能不如全表扫描高效。 总的来说,索引合并是一种强大的优化手段,能够显著提高复杂查询的效率。但是,它并不总是最优的选择,需要根据具体的数据分布和查询需求进行合理的选择和使用。

正文

本文分享自华为云社区《【华为云MySQL技术专栏】MySQL中为什么要使用索引合并(Index Merge)?》,作者:GaussDB 数据库。

在生产环境中,MySQL语句的where查询通常会包含多个条件判断,以AND或OR操作进行连接。然而,对一个表进行查询最多只能利用该表上的一个索引,其他条件需要在回表查询时进行判断(不考虑覆盖索引的情况)。当回表的记录数很多时,需要进行大量的随机IO,这可能导致查询性能下降。因此,MySQL 5.x 版本推出索引合并(Index Merge)来解决该问题。

本文将基于MySQL 8.0.22版本对MySQL的索引合并功能、实现原理及场景约束进行详细介绍,同时也会结合原理对其优缺点进行浅析,并通过例子进行验证。

什么是索引合并(Index Merge)?

索引合并是通过对一个表同时使用多个索引进行条件扫描,并将满足条件的多个主键集合取交集或并集后再进行回表,可以提升查询效率。

索引合并主要包含交集(intersection),并集(union)和排序并集(sort-union)三种类型:

  • intersection:将基于多个索引扫描的结果集取交集后返回给用户;
  • union:将基于多个索引扫描的结果集取并集后返回给用户;
  • sort-union:与union类似,不同的是sort-union会对结果集进行排序,随后再返回给用户;

MySQL中有四个开关(index_merge、index_merge_intersection、index_merge_union以及index_merge_sort_union)对上述三种索引合并类型提供支持,可以通过修改optimizer_switch系统参数中的四个开关标识来控制索引合并特性的使用。

假设创建表T,并插入如下数据:

CREATE TABLE T(  `id` int NOT NULL AUTO_INCREMENT,
`a` int NOT NULL,
`b` char(1) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_a` (`a`) USING BTREE,
KEY `idx_b` (`b`) USING BTREE
)ENGINE=InnoDB AUTO_INCREMENT=1;

INSERT INTO T (a, b) VALUES (1, 'A'), (2, 'B'),(3, 'C'),(4, 'B'),(1, 'C');

默认情况下,四个开关均为开启状态。如果需要单独使用某个合并类型,需设置index_merge=off,并将相应待启用的合并类型标识(例如,index_merge_sort_union)设置为on。

开关开启后,可通过EXPLAIN执行计划查看当前查询语句是否使用了索引合并。

mysql> explain SELECT * FROM T WHERE a=1 OR b='B';
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+---------------------------------------+
| id | select_type | table | partitions | type        | possible_keys | key         | key_len | ref  | rows | filtered | Extra                                 
|+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+---------------------------------------+
|  1 | SIMPLE      | T     | NULL       | index_merge | idx_a,idx_b   | idx_a,idx_b | 4,5     | NULL |    4 |   100.00 | Using union(idx_a,idx_b); Using where |
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+---------------------------------------+
1 row in set, 1 warning (0.01 sec)

上面代码显示type类型为index_merge,表示使用了索引合并。key列显示使用到的所有索引名称,该语句中同时使用了idx_a和idx_b两个索引完成查询。Extra列显示具体使用了哪种类型的索引合并,该语句显示Using union(...),表示索引合并类型为union。

此外,可以使用index_merge/no_index_merge给查询语句添加hint,强制SQL语句使用/不使用索引合并。

• 如果查询默认未使用索引合并,可以通过添加index_merge强制指定:

mysql> EXPLAIN SELECT * FROM T WHERE a=2 AND b='A';
+----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key   | key_len | ref   | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | T     | NULL       | ref  | idx_a,idx_b   | idx_a | 4       | const |    1 |    20.00 | Using where |
+----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
 

mysql> EXPLAIN SELECT /*+ INDEX_MERGE(T idx_a,idx_b) */ * FROM T WHERE a=2 AND b='A';
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+--------------------------------------------------------+
| id | select_type | table | partitions | type        | possible_keys | key         | key_len | ref  | rows | filtered | Extra                                                  |
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+--------------------------------------------------------+
|  1 | SIMPLE      | T     | NULL       | index_merge | idx_a,idx_b   | idx_a,idx_b | 4,5     | NULL |    1 |   100.00 | Using intersect(idx_a,idx_b); Using where; Using index |
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+--------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)

• 使用no_index_merge给查询语句添加hint,可以忽略索引合并优化:

mysql> EXPLAIN SELECT * FROM T WHERE a=1 OR b='A';
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+---------------------------------------+
| id | select_type | table | partitions | type        | possible_keys | key         | key_len | ref  | rows | filtered | Extra                                 |
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+---------------------------------------+
|  1 | SIMPLE      | T     | NULL       | index_merge | idx_a,idx_b   | idx_a,idx_b | 4,5     | NULL |    3 |   100.00 | Using union(idx_a,idx_b); Using where |
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+---------------------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> EXPLAIN SELECT /*+ NO_INDEX_MERGE(T idx_a,idx_b) */ * FROM T WHERE a=1 OR b='A';
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | T     | NULL       | ALL  | idx_a,idx_b   | NULL | NULL    | NULL |    5 |    36.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

索引合并(Index Merge)原理

1. Index Merge Intersection

Index Merge Intersection会在使用到的多个索引上同时进行扫描,并取这些扫描结果的交集作为最终结果集。

以“SELECT * FROM T WHERE a=1 AND b='C'; ”语句为例:

• 未使用索引合并时,MySQL利用索引idx_a获取到满足条件a=1的所有主键id,根据主键id进行回表查询到相关记录,随后再使用条件b='C'对这些记录进行判断,获取最终查询结果。

mysql> explain SELECT /*+ NO_INDEX_MERGE(T idx_a,idx_b) */ * FROM T WHERE a=1 AND b='C';
+----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key   | key_len | ref   | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | T     | NULL       | ref  | idx_a,idx_b   | idx_a | 4       | const |    2 |    40.00 | Using where |
+----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

• 使用索引合并时,MySQL分别利用索引idx_a和idx_b获取满足条件a=1和b='C'的主键id集合setA和setB。随后取setA和setB中主键id的交集setC,并使用setC中主键id进行回表,获取最终查询结果。

mysql> explain SELECT * FROM T WHERE a=1 AND b='C';
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+--------------------------------------------------------+
| id | select_type | table | partitions | type        | possible_keys | key         | key_len | ref  | rows | filtered | Extra                                                  |
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+--------------------------------------------------------+
|  1 | SIMPLE      | T     | NULL       | index_merge | idx_a,idx_b   | idx_a,idx_b | 4,5     | NULL |    1 |   100.00 | Using intersect(idx_a,idx_b); Using where; Using index |
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+--------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)

执行流程如下:

222.PNG

图1 SELECT * FROM T WHERE a=1 AND b='C';执行流程

2. Index Merge Union

Index Merge Union会在使用到的多个索引上同时进行扫描,并取这些扫描结果的并集作为最终结果集。

以“SELECT * FROM T WHERE a=1 OR b='B'; ”语句为例:

• 未使用索引合并时,MySQL通过全表扫描获取所有记录信息,随后再使用条件a=1和b='B'对这些记录进行判断,获取最终查询结果。

mysql> EXPLAIN SELECT /*+ NO_INDEX_MERGE(T idx_a,idx_b) */ * FROM T WHERE a=1 OR b='B';
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | T     | NULL       | ALL  | idx_a,idx_b   | NULL | NULL    | NULL |    5 |    50.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

• 使用索引合并算法时,MySQL分别利用索引idx_a和idx_b获取满足条件a=1和b='B'的主键id集合setA和setB。随后,取setA和setB中主键id的并集setC,并使用setC中主键id进行回表,获取最终查询结果。

mysql> EXPLAIN SELECT * FROM T WHERE a=1 OR b='B';
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+---------------------------------------+
| id | select_type | table | partitions | type        | possible_keys | key         | key_len | ref  | rows | filtered | Extra                                 |
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+---------------------------------------+
|  1 | SIMPLE      | T     | NULL       | index_merge | idx_a,idx_b   | idx_a,idx_b | 4,5     | NULL |    4 |   100.00 | Using union(idx_a,idx_b); Using where |
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+---------------------------------------+
1 row in set, 1 warning (0.01 sec)

执行流程如下:

333.PNG

图2 SELECT * FROM T WHERE a=1 OR b='B';执行流程

3. Index Merge Sort-Union

Sort-Union索引合并与Union索引合并原理相似,只是比单纯的Union索引合并多了一步对二级索引记录的主键id排序的过程。由OR连接的多个范围查询条件组成的WHERE子句不满足Union算法时,优化器会考虑使用Sort-Union算法。例如:

mysql> EXPLAIN SELECT * FROM T WHERE a<3 OR b<'B';
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+--------------------------------------------+
| id | select_type | table | partitions | type        | possible_keys | key         | key_len | ref  | rows | filtered | Extra                                      |
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+--------------------------------------------+
|  1 | SIMPLE      | T     | NULL       | index_merge | idx_a,idx_b   | idx_a,idx_b | 4,5     | NULL |    4 |   100.00 | Using sort_union(idx_a,idx_b); Using where |
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+--------------------------------------------+
1 row in set, 1 warning (0.00 sec)

应用场景约束

1. 总体约束

• Index Merge不能应用于全文索引(Fulltext Index)。
• Index Merge只能合并同一个表的索引扫描结果,不能跨表合并。

以上约束适用于Intersection,Union和Sort-Union三种合并类型。此外,Intersection和Union存在特殊的场景约束。

2. Index Merge Intersection

使用Intersection要求AND连接的每个条件必须是如下形式之一:

(1) 当索引包含多个列时,每个列都必须被如下等值条件覆盖,不允许出现范围查询。若使用索引为联合索引时,每个列都必须等值匹配,不能出现只匹配部分列的情况。

key_par1 = const1 AND key_par2 = const2 ... AND key_partN = constN

(2) 若过滤条件中存在主键列,主键列可以进行范围匹配。

mysql> EXPLAIN SELECT * FROM T WHERE id<3 AND b='A';
+----+-------------+-------+------------+-------------+---------------+---------------+---------+------+------+----------+---------------------------------------------+
| id | select_type | table | partitions | type        | possible_keys | key           | key_len | ref  | rows | filtered | Extra                                       |
+----+-------------+-------+------------+-------------+---------------+---------------+---------+------+------+----------+---------------------------------------------+
|  1 | SIMPLE      | T     | NULL       | index_merge | PRIMARY,idx_b | idx_b,PRIMARY | 9,4     | NULL |    1 |   100.00 | Using intersect(idx_b,PRIMARY); Using where |
+----+-------------+-------+------------+-------------+---------------+---------------+---------+------+------+----------+---------------------------------------------+
1 row in set, 1 warning (0.00 sec)

上述的要求,本质上是为了确保索引取出的记录是按照主键id有序排列的,因为Index Merge Intersection对两个有序集合取交集更简单。同时,主键有序的情况下,回表将不再是单纯的随机IO,回表的效率也会更高。

3. Index Merge Union

使用Union要求OR连接的每个条件,必须是如下形式之一:

(1) 当索引包含多个列时,则每个列都必须被如下等值条件覆盖,不允许出现范围查询。若使用索引为联合索引时,在联合索引中的每个列都必须等值匹配,不能出现只匹配部分列的情况。

key_par1 = const1 OR key_par2 = const2 ... OR key_partN = constN

(2) 若过滤条件中存在主键列,主键列可以进行范围匹配。

mysql> EXPLAIN SELECT * FROM T WHERE id>3 OR b='A';
+----+-------------+-------+------------+-------------+---------------+---------------+---------+------+------+----------+-----------------------------------------+
| id | select_type | table | partitions | type        | possible_keys | key           | key_len | ref  | rows | filtered | Extra                                   |
+----+-------------+-------+------------+-------------+---------------+---------------+---------+------+------+----------+-----------------------------------------+
|  1 | SIMPLE      | T     | NULL       | index_merge | PRIMARY,idx_b | PRIMARY,idx_b | 4,5     | NULL |    3 |   100.00 | Using union(PRIMARY,idx_b); Using where |
+----+-------------+-------+------------+-------------+---------------+---------------+---------+------+------+----------+-----------------------------------------+
1 row in set, 1 warning (0.00 sec)

Index Merge的优缺点

• Index Merge Intersection在使用到的多个索引上同时进行扫描,并取这些扫描结果的并集作为最终结果集。

当优化器根据搜索条件从某个索引中获取的记录数极多时,适合使用Intersection对取交集后的主键id以顺序I/O进行回表,其开销远小于使用随机IO进行回表。反之,当根据搜索条件扫描出的记录极少时,因为需要多一步合并操作,Intersection反而不占优势。在8.0.22版本,对于AND连接的点查场景,通过建立联合索引可以更好的减少回表。

• Index Merge Union在使用到的多个索引上同时进行扫描,并取这些扫描结果的并集作为最终结果集。

当优化器根据搜索条件从某个索引中获取的记录数比较少,通过Union索引合并后进行访问的代价比全表扫描更小时,使用Union的效果才会更优。

• Index Merge Sort-Union比单纯的Union索引合并多了一步对索引记录的主键id排序的过程。

当优化器根据搜索条件从某个索引中获取的记录数比较少的时,对这些索引记录的主键id进行排序的成本不高,此时可以加速查询。反之,当需要排序的记录过多时,该算法的查询效率不一定更优。

我们以Index Merge Union为例,对上述分析进行验证。

1. 场景构造

# 创建表CREATE TABLE T(  `id` int NOT NULL AUTO_INCREMENT,
`a` int NOT NULL,`
b` char(1) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_a` (`a`) USING BTREE,
KEY `idx_b` (`b`) USING BTREE
)ENGINE=InnoDB AUTO_INCREMENT=1;

# 插入数据
DELIMITER $$
CREATE PROCEDURE insertT()
BEGIN
DECLARE i INT DEFAULT 0;
START TRANSACTION;
WHILE i<=100000 do
if (i%100 = 0) then
INSERT INTO T (a, b) VALUES (10,CHAR(rand()*(90-65)+65));
else
INSERT INTO T (a, b) VALUES (i,CHAR(rand()*(90-65)+65));
end if;
SET i=i+1;
END WHILE;
COMMIT;
END$$
DELIMITER ;
call insertT();

# 执行测试语句
SQL1: SELECT * FROM T WHERE a=101 OR b='A';
SQL2: SELECT /*+ NO_INDEX_MERGE(T idx_a,idx_b) */ * FROM T WHERE a=101 OR b='A';
SQL3: SELECT * FROM T WHERE a=10 OR b='A';
SQL4: SELECT /*+ NO_INDEX_MERGE(T idx_a,idx_b) */ * FROM T WHERE a=10 OR b='A';

2. 执行结果及分析

每条语句查询5次,去掉最大值和最小值,取剩余三次结果平均值。4条语句查询结果如下:

测试语句

第一次查询/ms

第二次查询/ms

第三次查询/ms

第四次查询/ms

第五次查询/ms

平均值/ms

SQL1

5.481

5.422

5.117

4.892

5.426

5.322

SQL2

31.129

32.645

30.943

31.142

32.625

31.632

SQL3

7.872

7.200

7.824

7.955

7.949

7.882

SQL4

31.139

33.318

31.476

31.645

31.27

31.464

对比使用索引合并的SQL1和未使用索引合并的SQL2的查询结果可知,使用索引合并的SQL1具有更高的查询效率,这点从语句的explain analyze分析中也可以看出:

使用索引合并的SQL1代码示例:

EXPLAIN ANALYZE SELECT * FROM T WHERE a=101 OR b='A';
-> Filter: ((t.a = 101) or (t.b = 'A'))  (cost=717.14 rows=2056) (actual time=0.064..5.481 rows=2056 loops=1)
-> Index range scan on T using union(idx_a,idx_b)  (cost=717.14 rows=2056) (actual time=0.062..5.120 rows=2056 loops=1)

未使用索引合并的SQL2代码示例:

EXPLAIN ANALYZE SELECT /*+ NO_INDEX_MERGE(T idx_a,idx_b) */ * FROM T WHERE a=101 OR b='A';
-> Filter: ((t.a = 101) or (t.b = 'A'))  (cost=10098.75 rows=10043) (actual time=0.038..31.129 rows=2056 loops=1)
-> Table scan on T  (cost=10098.75 rows=100425) (actual time=0.031..22.967 rows=100001 loops=1)

未使用索引合并时,SQL2语句需要花费约23ms来扫描全表100001行数据,随后再进行条件判断。而使用索引合并时,通过合并两个索引筛选出的主键id集合,筛选出2056个符合条件的主键id, 随后回表获取最终的数据。这个环节中,索引合并大大减少了需要访问的记录数量。

此外,从SQL1和SQL3的查询结果也可以看出,数据分布也会影响索引合并的效果。相同的SQL模板类型,根据匹配数值的不同,查询时间存在差异。如需要合并的主键id集合越小,需要回表的主键id越少,查询时间越短。

EXPLAIN ANALYZE SELECT * FROM T WHERE a=101 OR b='A';
-> Filter: ((t.a = 101) or (t.b = 'A'))  (cost=717.14 rows=2056) (actual time=0.064..5.481 rows=2056 loops=1)
   -> Index range scan on T using union(idx_a,idx_b)  (cost=717.14 rows=2056) (actual time=0.062..5.120 rows=2056 loops=1)
 

EXPLAIN ANALYZE SELECT * FROM T WHERE a=10 OR b='A';
-> Filter: ((t.a = 10) or (t.b = 'A'))  (cost=983.00 rows=3057) (actual time=0.070..7.872 rows=3035 loops=1)
   -> Index range scan on T using union(idx_a,idx_b)  (cost=983.00 rows=3057) (actual time=0.068..7.496 rows=3035 loops=1)

总结

本文介绍了索引合并(Index Merge)包含的三种类型,即交集(intersection)、并集(union)和排序并集(sort-union),以及索引合并的实现原理、场景约束与通过案例验证的优缺点。在实际使用中,当查询条件列较多且无法使用联合索引时,就可以考虑使用索引合并,利用多个索引加速查询。但要注意,索引合并并非在任何场景下均具有较好的效果,需要结合具体的数据分布进行算法的选择。

 

点击关注,第一时间了解华为云新鲜技术~

 

与MySQL中为什么要使用索引合并(Index Merge)?相似的内容:

MySQL中为什么要使用索引合并(Index Merge)?

本文介绍了索引合并(Index Merge)包含的三种类型,即交集(intersection)、并集(union)和排序并集(sort-union),以及索引合并的实现原理、场景约束与通过案例验证的优缺点。

【转帖】《MySQL高级篇》四、索引的存储结构

1. 为什么使用索引 假如给数据使用 二叉树 这样的数据结构进行存储,如下图所示 2、索引及其优缺点 2.1 索引概述 2.2 优点 类似大学图书馆建书目索引,提高数据检索的效率,降低 数据库的 IO 成本 这也是创建索引的主要的原因。通过创建唯一索引,可以保证数据库表中每一行 数据的唯一性 (唯一

[转帖]使用 Dumpling 导出数据

16 Contributors 使用数据导出工具 Dumpling,你可以把存储在 TiDB 或 MySQL 中的数据导出为 SQL 或 CSV 格式,用于逻辑全量备份。Dumpling 也支持将数据导出到 Amazon S3 中。 要快速了解 Dumpling 的基本功能,建议先观看下面的培训视频

[转帖]MySQL定点数类型DECIMAL用法详解

https://www.cnblogs.com/danielzzz/p/16824214.html 一、MySQL DECIMAL 的使用 DECIMAL 数据类型用于在数据库中存储精确的数值,我们经常将该数据类型用于保留准确精确度的列,例如会计系统中的货币数据。 要定义数据类型为DECIMAL的列

[转帖]一致性哈希 和 Redis 集群分槽

前言 伴随着系统流量的增大,出现了应用集群。在 Redis 中为了保证 Redis 的高可用也为 Redis 搭建了集群对数据进行分槽存放。在 Mysql数据库要存储的量达到一个很高的地步的时候,我们会对数据库进行分库分表操作。OK,到这儿先假设我们不知道什么是集群、什么是分库分表,我们先来看一个数

[转帖]一文看懂mysql数据库事务隔离级别

概述 我们都知道除了MySQL默认采用RR隔离级别之外,其它几大数据库都是采用RC隔离级别。那为啥mysql要这样设置呢?其实是MySQL为了规避一个数据复制场景中的缺陷,而选择 Repeatable Read 作为默认隔离级别。不过不同数据库实现方式还是不太一样。 Oracle仅仅实现了RC 和

为什么MySQL单表不能超过2000万行?

摘要:MySQL一张表最多能存多少数据? 本文分享自华为云社区《为什么MySQL单表不能超过2000万行?》,作者: GaussDB 数据库 。 最近看到一篇《我说MySQL每张表最好不要超过2000万数据,面试官让我回去等通知》的文章,非常有趣。 文中提到,他朋友在面试的过程中说,自己的工作就是把

深入理解MySQL索引底层数据结构

在日常工作中,我们会遇见一些慢SQL,在分析这些慢SQL时,我们通常会看下SQL的执行计划,验证SQL执行过程中有没有走索引。通常我们会调整一些查询条件,增加必要的索引,SQL执行效率就会提升几个数量级。我们有没有思考过,为什么加了索引就会能提高SQL的查询效率,为什么有时候加了索引SQL执行反而会没有变化,本文就从MySQL索引的底层数据结构和算法来进行详细分析。

【转帖】Mysql一张表可以存储多少数据

https://www.cnblogs.com/wenbochang/p/16723537.html Mysql一张表可以存储多少数据 在操作系统中,我们知道为了跟磁盘交互,内存也是分页的,一页大小4KB。同样的在MySQL中为了提高吞吐率,数据也是分页的,不过MySQL的数据页大小是16KB。(确

DBA必备的Mysql知识点:数据类型和运算符

摘要:本文主要为大家带来Mysql中的3种数据类型和3种运算符。 本文分享自华为云社区《Mysql中的数据类型和运算符》,作者: 1+1=王。 Mysql的数据类型 Mysql支持数值型、文本型和日期时间型三大数据类型。 数值型数据 数值型是描述定量数据的数据类型,包括整数型数据类型和浮点型数据类型