- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
本文分享自华为云社区《【华为云MySQL技术专栏】MySQL中为什么要使用索引合并(Index Merge)?》,作者:GaussDB 数据库.
在生产环境中,MySQL语句的where查询通常会包含多个条件判断,以AND或OR操作进行连接。然而,对一个表进行查询最多只能利用该表上的一个索引,其他条件需要在回表查询时进行判断(不考虑覆盖索引的情况)。当回表的记录数很多时,需要进行大量的随机IO,这可能导致查询性能下降。因此,MySQL 5.x 版本推出索引合并(Index Merge)来解决该问题.
本文将基于MySQL 8.0.22版本对MySQL的索引合并功能、实现原理及场景约束进行详细介绍,同时也会结合原理对其优缺点进行浅析,并通过例子进行验证.
索引合并是通过对一个表同时使用多个索引进行条件扫描,并将满足条件的多个主键集合取交集或并集后再进行回表,可以提升查询效率.
索引合并主要包含交集(intersection),并集(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 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)
执行流程如下:
图1 SELECT * FROM T WHERE a=1 AND b='C';执行流程 。
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)
执行流程如下:
图2 SELECT * FROM T WHERE a=1 OR b='B';执行流程 。
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)
以上约束适用于Intersection,Union和Sort-Union三种合并类型。此外,Intersection和Union存在特殊的场景约束.
使用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,回表的效率也会更高.
使用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 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为例,对上述分析进行验证.
# 创建表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';
每条语句查询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中为什么要使用索引合并(IndexMerge)?的文章就讲到这里了,如果你想了解更多关于MySQL中为什么要使用索引合并(IndexMerge)?的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
这几天我一直在努力。我一直在自学 CSS,所以对菜鸟好一点。我正在创建一个推荐 slider 。推荐以 3 个 block 显示。我希望前 2 个下降,第 3 个上升。但是当 slider 激活时,无
我最近开始学习 Nodejs,现在我很困惑我的网络应用程序使用什么,html 还是 ejs (Express)。 Ejs 使用 Express 模块,而 .html 使用 HTML 模块。我的第一个问
假设我们有一个 PostgreSQL 表contacts,每条记录都有一堆带标签的电子邮件地址(标签和电子邮件对)——其中一个是“主要”。 存储方式如下: id 主键 电子邮件 文本 email_la
我成功为一种新的tesseract语言编写了traineddata文件,但是当我完成时,我继续收到以下错误: index >= 0 && index = 0 && 索引 < size_used_ :E
这个问题已经有答案了: How to deal with SettingWithCopyWarning in Pandas (21 个回答) 已关闭 4 年前。 假设我有一个像这样的数据框,第一列“密
如果我有一个位置或行/列同时用于 A 和 B 位置,请检查 B 是否与 A 成对角线? 1 2 3 4 5 6 7 8 9 例如,我如何检查 5 是否与 7 成对角线? 此外,如果我检查 4 是
MongoDB:索引 一、 创建索引 默认情况下,集合中的_id字段就是索引,我们可以通过getIndexes()方法来查看一个集合中的索引 > db.user.getIndexes() [ { "v
一、索引介绍 索引是一种用来快速查询数据的数据结构。 B+Tree就是一种常用的数据库索引数据结构,MongoDB采用B+Tree 做索引,索引创建在colletions上。 MongoDB不使用索引
我无法决定索引。 就像我有下面的查询需要太多时间来执行: select count(rn.NODE_ID) as Count, rnl.[ISO_COUNTRY_CODE] as Cou
我有这些表: CREATE TABLE `cstat` ( `id_cstat` bigint(20) NOT NULL, `lang_code` varchar(3) NOT NULL,
我正在尝试找到一种方法来提高包含 IP 范围的 mysql 表的性能(在高峰时段每秒最多有 500 个 SELECT 查询(!),所以我有点担心)。 我有一个这种结构的表: id smallint(
jquery index() 似乎无法识别元素之一,总是说“无法读取未定义的属性‘长度’”这是我的代码。mnumber 是导致问题的原因。我需要 number 和 mnumber 才能跟踪使用鼠标,并
我们有一个包含近 4000 万条记录的 MongoDB 集合。该集合的当前大小为 5GB。此集合中存储的数据包含以下字段: _id: "MongoDB id" userid: "user id" (i
文档说:如果你有多个字段的复合索引,你可以用它来查询字段的开始子集。所以如果你有一个索引一个,乙,丙你可以用它查询一种一个,乙a,b,c 我的问题是,如果我有一个像这样的复合索引一个,乙,丙我可以查询
我正在使用 $('#list option').each(function(){ //do stuff }); 循环列表中的选项。我想知道如何获取当前循环的索引? 因为我不想让 var i = 0;循
MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。 打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL
SQLite 索引(Index) 索引(Index)是一种特殊的查找表,数据库搜索引擎用来加快数据检索。简单地说,索引是一个指向表中数据的指针。一个数据库中的索引与一本书后边的索引是非常相似的。
我是 RavenDB 的新手。我正在尝试使用多 map 索引功能,但我不确定这是否是解决我的问题的最佳方法。所以我有三个文件:Unit、Car、People。 汽车文件看起来像这样: { Id: "
我有以下数据,我想根据范围在另一个表中建立索引 我想要实现的是,例如,如果三星的销售额为 2500,则折扣为 2%,低于 3000 且高于 1000 我知道它可以通过索引来完成,与多个数组匹配,然后指
我正在检查并删除 SQL 数据库中的重复和冗余索引。 所以如果我有两个相同的索引,我会删除。 例如,如果我删除了重叠的索引... 索引1:品牌、型号 指标二:品牌、型号、价格 我删除索引 1。 相同顺
我是一名优秀的程序员,十分优秀!