Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

10.2.1.3 索引合并优化

索引合并 访问方法检索具有多个 范围 扫描的行,并将其结果合并为一个。这访问方法仅合并单个表的索引扫描,而不是跨多个表的扫描。合并可以生成基础扫描的并集、交集或并集交集。

可能使用 Index Merge 的示例查询:

SELECT * FROM tbl_name WHERE key1 = 10 OR key2 = 20;

SELECT * FROM tbl_name
  WHERE (key1 = 10 OR key2 = 20) AND non_key = 30;

SELECT * FROM t1, t2
  WHERE (t1.key1 IN (1,2) OR t1.key2 LIKE 'value%')
  AND t2.key1 = t1.some_col;

SELECT * FROM t1, t2
  WHERE t1.key1 = 1
  AND (t2.key1 = t1.some_col OR t2.key2 = t1.some_col2);
Note

Index Merge 优化算法具有以下已知限制:

  • 如果您的查询具有复杂的 WHERE 子句,具有深层 AND/OR 嵌套,并且 MySQL 未选择最佳计划,请尝试使用以下身份转换来分布术语:

    (x AND y) OR z => (x OR z) AND (y OR z)
    (x OR y) AND z => (x AND z) OR (y AND z)
  • Index Merge 不适用于全文索引。

EXPLAIN 输出中,Index Merge 方法显示为 index_mergetype 列中。在这种情况下,key 列包含使用的索引列表,key_len 列包含这些索引的最长键部分。

Index Merge 访问方法具有多种算法,这些算法在 Extra 字段的 EXPLAIN 输出中显示:

  • Using intersect(...)

  • Using union(...)

  • Using sort_union(...)

以下部分详细描述这些算法。优化器根据可用选项的成本估算选择不同的 Index Merge 算法和其他访问方法。

索引合并交集访问算法

该访问算法适用于 WHERE 子句被转换为多个范围条件的不同键,使用 AND 结合,每个条件都是以下之一:

  • 一个 N-部分表达式,该索引恰好具有 N 部分(即所有索引部分都被涵盖):

    key_part1 = const1 AND key_part2 = const2 ... AND key_partN = constN
  • 任何范围条件,位于 InnoDB 表的主键上。

示例:

SELECT * FROM innodb_table
  WHERE primary_key < 10 AND key_col1 = 20;

SELECT * FROM tbl_name
  WHERE key1_part1 = 1 AND key1_part2 = 2 AND key2 = 2;

索引合并交集算法同时扫描所有使用的索引,并生成从合并的索引扫描中接收的行序列的交集。

如果查询中使用的所有列都被使用的索引所涵盖,则不检索完整的表行 (EXPLAIN 输出包含 Using indexExtra 字段中)。以下是一个示例查询:

SELECT COUNT(*) FROM t1 WHERE key1 = 1 AND key2 = 1;

如果使用的索引不涵盖查询中使用的所有列,则仅在所有使用的键的范围条件都满足时检索完整的表行。

如果其中一个合并条件是 InnoDB 表的主键上的条件,则它不用于检索行,而是用于过滤使用其他条件检索的行。

索引合并并集访问算法

该算法的标准与索引合并交集算法相似。该算法适用于表的 WHERE 子句被转换为多个范围条件的不同键,使用 OR 结合,每个条件都是以下之一:

  • 一个 N-部分表达式,以这种形式,其中索引恰好有 N 部分(即所有索引部分都被涵盖):

    key_part1 = const1 OR key_part2 = const2 ... OR key_partN = constN
  • 任何在 InnoDB 表的主键上的范围条件。

  • 适用 Index Merge 交集算法的条件。

示例:

SELECT * FROM t1
  WHERE key1 = 1 OR key2 = 2 OR key3 = 3;

SELECT * FROM innodb_table
  WHERE (key1 = 1 AND key2 = 2)
     OR (key3 = 'foo' AND key4 = 'bar') AND key5 = 5;
索引合并排序-union 访问算法

WHERE 子句被转换为多个范围条件,使用 OR 结合,但 Index Merge union 算法不可用时,该访问算法适用。

示例:

SELECT * FROM tbl_name
  WHERE key_col1 < 10 OR key_col2 < 20;

SELECT * FROM tbl_name
  WHERE (key_col1 > 10 OR key_col2 = 20) AND nonkey_col = 30;

sort-union 算法与 union 算法的区别在于,sort-union 算法必须首先获取所有行的行 ID,然后对其进行排序,最后返回行。

影响索引合并优化

索引合并的使用取决于 index_mergeindex_merge_intersectionindex_merge_unionindex_merge_sort_union 标志的值,这些标志是 optimizer_switch 系统变量的一部分。见 第 10.9.2 节,“可切换优化”。默认情况下,这些标志都是 on。要启用某些算法,请将 index_merge 设置为 off,然后启用其他所需的标志。

除了使用 optimizer_switch 系统变量来控制优化器对索引合并算法的使用外,MySQL 还支持优化器提示,以便在每个语句的基础上影响优化器。见 第 10.9.3 节,“优化器提示”