mysql - 为什么 MySQL(MyISAM 和 InnoDB)不使用我的索引?

标签 mysql wordpress indexing innodb myisam

这是我的 table :

CREATE TABLE `wp_postmeta` (
  `meta_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `post_id` bigint(20) unsigned NOT NULL DEFAULT '0',
  `meta_key` varchar(255) DEFAULT NULL,
  `meta_value` longtext,
  `meta_value_integer` int(11) DEFAULT NULL,
  `meta_value_date` date DEFAULT NULL,
  PRIMARY KEY (`meta_id`),
  KEY `post_id` (`post_id`),
  KEY `meta_key` (`meta_key`),
  KEY `post_meta_integer` (`meta_key`,`meta_value_integer`),
  KEY `post_meta_date` (`meta_key`,`meta_value_date`)
) ENGINE=MyISAM AUTO_INCREMENT=2050 DEFAULT CHARSET=utf8

您可以从 WordPress 识别它,但我添加了两个额外的列来将 meta_value 存储为整数,一个存储为日期。我还在 (meta_key, meta_value_integer) 和 (meta_key, meta_value_date) 上添加了索引,其余的以前就在那里。

现在我只是想知道为什么 MySQL 在这样的查询中选择 meta_key 索引而不是 post_meta_integer 键:

mysql> EXPLAIN SELECT * FROM wp_postmeta WHERE meta_key = 'price' AND meta_value_integer > 1000;
+----+-------------+-------------+------+-----------------------+----------+---------+-------+------+-------------+
| id | select_type | table       | type | possible_keys         | key      | key_len | ref   | rows | Extra       |
+----+-------------+-------------+------+-----------------------+----------+---------+-------+------+-------------+
|  1 | SIMPLE      | wp_postmeta | ref  | meta_key,meta_integer | meta_key | 768     | const |    9 | Using where |
+----+-------------+-------------+------+-----------------------+----------+---------+-------+------+-------------+
1 row in set (0.00 sec)

我也试过 less than 和 BETWEEN 但没有运气。如果我将比较更改为 = 尽管它使用 meta_integer 键。也许这与我不知道的数据集有关。 meta_value_integer 和日期也有很多 NULL 值(例如,在 meta_value 中使用字符串)。

所以我想知道为什么 MySQL 更喜欢 meta_key 索引以及我做错了什么。我真的很想优化架构,因为帖子元中可能有 200,000 行不同的行,其中只有 20 行可能是价格。所以理想情况下,我希望 meta_value_integer 索引小于整个 meta_key 索引。这可能吗?

谢谢!

最佳答案

您在 meta_key 上进行选择,因此使用该索引是合乎逻辑的。 MySQL 不能同时使用这两个索引。

解决方案:您可以在两列(meta_key 是第一列)上创建一个组合键,并为整数字段创建一个单独的键。在对两列(就像您现在所做的那样)或单独对第一列 meta_key 进行过滤时,将使用组合键。当您单独过滤整数字段时,将使用整数键。

关于mysql - 为什么 MySQL(MyISAM 和 InnoDB)不使用我的索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7982407/

相关文章:

javascript - jQuery 选择框未关闭

c++ - 重载索引运算符

java - 如何使用 Java 索引整个硬盘/文件系统?

mysql - 按存在于 created_at 之前的关联排序

php - 外键约束使 SELECT 查询返回 0 行

android - 如何在android中分享帖子的内容?

php - 我无法在我的 wordpress 网站的插件中加载我的自定义样式

php - Wordpress 开发 VS 生产环境

postgresql - 搜索表达索引

mysql 外键错误 #1452