• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 不可见索引

    MySQL支持不可见索引;也就是说,优化器未使用的索引。该功能适用于除主键(显式或隐式)以外的索引。

    默认情况下,索引可见。为了控制指标的可视性明确了新的索引,使用一个VISIBLEINVISIBLE关键字作为指标定义的一部分CREATE TABLECREATE INDEX或者ALTER TABLE

    CREATE TABLE t1 (
      i INT,
      j INT,
      k INT,
      INDEX i_idx (i) INVISIBLE
    ) ENGINE = InnoDB;
    CREATE INDEX j_idx ON t1 (j) INVISIBLE;
    ALTER TABLE t1 ADD INDEX k_idx (k) INVISIBLE;
    

    要更改现有索引的可见性,请在操作中使用VISIBLEINVISIBLE关键字ALTER TABLE ... ALTER INDEX

    ALTER TABLE t1 ALTER INDEX i_idx INVISIBLE;
    ALTER TABLE t1 ALTER INDEX i_idx VISIBLE;
    

    有关索引是可见还是不可见的信息可从INFORMATION_SCHEMA.STATISTICS表或SHOW INDEX输出中获得。例如:

    mysql> SELECT INDEX_NAME, IS_VISIBLE
           FROM INFORMATION_SCHEMA.STATISTICS
           WHERE TABLE_SCHEMA = 'db1' AND TABLE_NAME = 't1';
    +------------	+------------	+
    | INDEX_NAME 	| IS_VISIBLE 	|
    +------------	+------------	+
    | i_idx      	| YES        	|
    | j_idx      	| NO         	|
    | k_idx      	| NO         	|
    +------------	+------------	+
    

    不可见的索引可以测试删除索引对查询性能的影响,而无需进行破坏性的更改,如果需要该索引,则必须撤消该更改。对于大型表,删除和重新添加索引可能会很昂贵,而使其不可见和可见则是快速的就地操作。

    如果优化程序实际上需要或使用使索引变为不可见的索引,则有几种方法可以注意到缺少索引对表查询的影响:

    • 对于包含引用不可见索引的索引提示的查询,会发生错误。
    • 性能架构数据显示了受影响查询的工作量增加。
    • 查询具有不同的EXPLAIN执行计划。
    • 查询出现在慢查询日志中,以前没有出现在查询日志中。

    系统变量的use_invisible_indexes标志optimizer_switch控制优化器是否使用不可见索引来构建查询执行计划。如果该标志是off(缺省值),那么优化器将忽略不可见索引(与引入该标志之前的行为相同)。如果该标志为on,则不可见索引将保持不可见,但优化程序会将其考虑在内以执行执行计划。

    索引可见性不影响索引维护。例如,对于表行的更改,索引将继续更新,并且唯一索引可防止将重复项插入到列中,而不管索引是可见还是不可见。

    没有显式主键的表如果UNIQUENOT NULL列上有任何索引,则仍可能具有有效的隐式主键。在这种情况下,第一个这样的索引对表行施加与显式主键相同的约束,并且该索引不能不可见。考虑以下表定义:

    CREATE TABLE t2 (
      i INT NOT NULL,
      j INT NOT NULL,
      UNIQUE j_idx (j)
    ) ENGINE = InnoDB;
    

    该定义不包含显式主键,但是NOT NULL列上的索引j对行的约束与主键相同,并且不能使其不可见:

    mysql> ALTER TABLE t2 ALTER INDEX j_idx INVISIBLE;
    ERROR 3522 (HY000): A primary key index cannot be invisible.
    

    现在,假设将一个显式主键添加到表中:

    ALTER TABLE t2 ADD PRIMARY KEY (i);
    

    显式主键不能不可见。此外,上的唯一索引j不再充当隐式主键,因此可以使其不可见:

    mysql> ALTER TABLE t2 ALTER INDEX j_idx INVISIBLE;
    Query OK, 0 rows affected (0.03 sec)