简体   繁体   English

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

[英]Why is MySQL (MyISAM and InnoDB) not using my index?

Here's my 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

You can recognize it form WordPress but I added two extra columns to store the meta_value as an integer and one as a date. 您可以通过WordPress识别它,但我添加了两个额外的列来将meta_value存储为整数,将一个存储为日期。 I've also added indices on (meta_key, meta_value_integer) and (meta_key, meta_value_date), the rest was there before. 我还在(meta_key,meta_value_integer)和(meta_key,meta_value_date)上添加了索引,其余的都在那之前。

Now I'm just wondering why is MySQL picking the meta_key index and not the post_meta_integer key on a query like this: 现在我只是想知道为什么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)

I tried less than and BETWEEN too but no luck. 我尝试的次数少于和BETWEEN但没有运气。 If I change the comparison to = though it uses the meta_integer key. 如果我将比较更改为=虽然它使用meta_integer键。 Maybe it's related to my dataset I don't know. 也许与我不知道的数据集有关。 There are a lot of NULL values for meta_value_integer and dates too (where strings are used in meta_value for example). meta_value_integer和日期也有很多NULL值(例如,在meta_value中使用字符串)。

So I'd like to know why does MySQL prefer the meta_key index and what am I doing wrong. 所以我想知道为什么MySQL偏爱meta_key索引,我在做什么错。 I'd really like to optimize the schema since there may be 200,000 different rows in posts meta and only 20 of them might be the prices. 我真的很想优化架构,因为post meta中可能有200,000个不同的行,而其中只有20个是价格。 So ideally I'd like the meta_value_integer index to be smaller than the whole meta_key index. 因此,理想情况下,我希望meta_value_integer索引小于整个meta_key索引。 Is that possible? 那可能吗?

Thanks! 谢谢!

You're selecting on meta_key, so it's quite logical that it uses that index. 您正在选择meta_key,因此它使用该索引是合乎逻辑的。 MySQL cannot use both indexes. MySQL不能同时使用这两个索引。

Solution: You can create a combined key on both columns (meta_key being the first column) and a separate key for the integer field. 解决方案:您可以在两列上创建组合键(meta_key为第一列),并为整数字段创建单独的键。 The combined key will be used when filtering on both columns (like you do now) or on meta_key, the first column, alone. 在两列(如您现在所做的)或单独在第一列meta_key上进行过滤时,将使用组合键。 The integer key will be used when you filter on the integer field alone. 当您仅对整数字段进行过滤时,将使用整数键。

如果MySQL最好猜测使用哪个索引并不是你想到的,你可以尝试使用索引提示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM