Почему MySQL (MyISAM и InnoDB) не использует мой индекс? - PullRequest
1 голос
/ 02 ноября 2011

Вот мой стол:

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. Это возможно?

спасибо!

Ответы [ 2 ]

2 голосов
/ 02 ноября 2011

Вы выбираете на meta_key, так что вполне логично, что он использует этот индекс.MySQL не может использовать оба индекса.

Решение: Вы можете создать комбинированный ключ для обоих столбцов (meta_key - первый столбец) и отдельный ключ для целочисленного поля.Комбинированный ключ будет использоваться при фильтрации по обоим столбцам (как вы делаете сейчас) или по мета-ключу, только в первом столбце.Целочисленная клавиша будет использоваться, когда вы фильтруете только одно целочисленное поле.

1 голос
/ 02 ноября 2011

Если MySQL лучше не использует тот индекс, который вы хотите использовать, вы можете попробовать указатель индекса .

...