MySQL 可以满足前缀索引的查询吗?
Can MySQL satisfy a query from a prefix index?
我想知道覆盖索引是否可以帮助某些行满足来自 LONGTEXT 或任何其他 LOB 列的查询? (MySQL 8,MariaDB 10.5)
我有这个 table(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';
它 returns 几百行(在许多繁忙的 WordPress 安装中)。这些行中的大多数具有相当短的 option_name、option_value 字符串,但少数可以具有长字符串。 WordPress 经常使用这个查询(在每个页面视图上)。它使用 autoload
索引来满足 WHERE
条件。
我的问题:如果我定义一个包含如下前缀的覆盖索引:
wp_options(autoload, option_name(40), option_value(131))
索引扫描是否可以直接满足短名称和短值的查询?
或者 MySQL 是否在主 table 中查找每个 option_name
和每个 option_value
的 LONGTEXT 对象,是否短?
您无法从前缀索引中获得覆盖索引的好处。
即使您需要的值适合前缀,MySQL 在制定优化程序计划时也不知道。它在读取任何数据行之前制定优化器计划,因此它必须假设至少在某些行上,该列中的值将比前缀长,并且它必须从中读取字符串的其余部分指数之外。所以它没有通过仅从索引读取来利用覆盖索引效果。
这里有一个演示:https://www.percona.com/blog/2006/11/23/covering-index-and-prefix-indexes/
那是一篇旧博客,所以如果有人想知道是否同样适用于 MySQL 的当前版本,博客中显示的步骤很容易重现。
我想知道覆盖索引是否可以帮助某些行满足来自 LONGTEXT 或任何其他 LOB 列的查询? (MySQL 8,MariaDB 10.5)
我有这个 table(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';
它 returns 几百行(在许多繁忙的 WordPress 安装中)。这些行中的大多数具有相当短的 option_name、option_value 字符串,但少数可以具有长字符串。 WordPress 经常使用这个查询(在每个页面视图上)。它使用 autoload
索引来满足 WHERE
条件。
我的问题:如果我定义一个包含如下前缀的覆盖索引:
wp_options(autoload, option_name(40), option_value(131))
索引扫描是否可以直接满足短名称和短值的查询?
或者 MySQL 是否在主 table 中查找每个 option_name
和每个 option_value
的 LONGTEXT 对象,是否短?
您无法从前缀索引中获得覆盖索引的好处。
即使您需要的值适合前缀,MySQL 在制定优化程序计划时也不知道。它在读取任何数据行之前制定优化器计划,因此它必须假设至少在某些行上,该列中的值将比前缀长,并且它必须从中读取字符串的其余部分指数之外。所以它没有通过仅从索引读取来利用覆盖索引效果。
这里有一个演示:https://www.percona.com/blog/2006/11/23/covering-index-and-prefix-indexes/ 那是一篇旧博客,所以如果有人想知道是否同样适用于 MySQL 的当前版本,博客中显示的步骤很容易重现。