【问题标题】:Can MySQL satisfy a query from a prefix index?MySQL 可以满足来自前缀索引的查询吗?
【发布时间】:2021-07-22 21:57:02
【问题描述】:

我想知道覆盖索引是否可以帮助某些行满足来自 LONGTEXT 或任何其他 LOB 列的查询? (MySQL 8,MariaDB 10.5)

我有这张表(WordPress 定义的):

CREATE TABLE wp_options (
    option_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    option_name VARCHAR(191) NOT NULL DEFAULT '' COLLATE 'utf8mb4_unicode_ci',
    option_value LONGTEXT NOT NULL COLLATE 'utf8mb4_unicode_ci',
    autoload VARCHAR(20) NOT NULL DEFAULT 'yes' COLLATE 'utf8mb4_unicode_ci',
    PRIMARY KEY (option_id) USING BTREE,
    UNIQUE INDEX option_name (option_name) USING BTREE,
    INDEX autoload (autoload) USING BTREE
) ENGINE=InnoDB;

我需要运行这个查询:

SELECT option_name, option_value FROM wp_options WHERE autoload='yes';

它返回数百行(在许多繁忙的 WordPress 安装中)。这些行中的大多数都有相当短的 option_name、option_value 字符串,但少数可以有很长的字符串。 WordPress 经常使用这个查询(在每个页面视图上)。它使用autoload 索引来满足WHERE 条件。

我的问题:如果我定义一个包含前缀的覆盖索引,如下所示:

 wp_options(autoload, option_name(40), option_value(131))

索引扫描能否直接满足对较短名称和值的查询? 或者 MySQL 是否在主表中查找每个 option_name 和每个 option_value 的 LONGTEXT 对象,无论它是否短?

【问题讨论】:

    标签: mysql mariadb query-optimization longtext covering-index


    【解决方案1】:

    您无法从前缀索引中获得覆盖索引的好处。

    即使您需要的值符合前缀,MySQL 在制定优化器计划时也不知道这一点。它在读取任何数据行之前制定优化器计划,因此它必须假设至少在某些行上,该列中的值将比前缀长,并且它必须从指数之外。所以它并没有通过只从索引中读取来利用覆盖索引的效果。

    这里有一个演示:https://www.percona.com/blog/2006/11/23/covering-index-and-prefix-indexes/ 那是一个旧博客,所以如果有人想知道这是否适用于当前版本的 MySQL,那么博客中显示的步骤很容易重现。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-29
      • 2021-06-19
      • 2015-10-10
      • 1970-01-01
      • 2014-10-20
      • 2018-12-31
      • 1970-01-01
      相关资源
      最近更新 更多