微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

MySQL 可以满足来自前缀索引的查询吗?

如何解决MySQL 可以满足来自前缀索引的查询吗?

我想知道覆盖索引是否可以帮助某些行满足来自 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 在制定优化器计划时也不知道。它在读取任何数据行之前制定优化器计划,因此它必须假设至少在某些行上,该列中的值将长于前缀,并且必须从中读取字符串的其余部分指数之外。所以只从索引中读取并没有利用覆盖索引的效果。

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。