Вот мой стол:
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)
Я пробовал меньше, чем и между тоже, но не повезло. Если я изменю сравнение на =
, хотя оно использует ключ meta_integer. Может быть, это связано с моим набором данных, я не знаю. Существует много значений NULL для meta_value_integer и дат (в том числе строки используются, например, в meta_value).
Итак, я хотел бы знать, почему MySQL предпочитает индекс meta_key
и что я делаю неправильно. Мне бы очень хотелось оптимизировать схему, поскольку в мета-сообщениях может быть 200 000 разных строк, и только 20 из них могут быть ценами. Поэтому в идеале я бы хотел, чтобы индекс meta_value_integer был меньше, чем весь индекс meta_key. Это возможно?
спасибо!