Неожиданное сканирование индекса в плане запросов MySQL - PullRequest
1 голос
/ 07 октября 2010

Я получаю сканирование индекса по соединению с уникальным столбцом;он утверждает, что проверяет большое количество строк, даже когда ищет только одну строку.

Это запрос:

    select t.id, 
           t.twitter_id, 
           t.screen_name,  
           t.text     
      from tweets t 
inner join twitter_handle th on th.handle = t.screen_name 
  order by t.created_at desc 
     limit 1;

Добавление / удаление предложения limit не меняетплан запроса.Я ожидаю, что он будет сканировать по индексу созданного твита твиттеров на количество строк, равное числу в предложении limit, а затем выполнить поиск eq_ref против twitter_handle.

План запроса в соответствии с объяснением, однако,это:

+----+-------------+-------+-------+---------------+-------------+---------+------+--------+----------------------------------------------+
| id | select_type | table | type  | possible_keys | key         | key_len | ref  | rows   | Extra                                        |
+----+-------------+-------+-------+---------------+-------------+---------+------+--------+----------------------------------------------+
|  1 | SIMPLE      | th    | index | NULL          | handle      | 32      | NULL | 100126 | Using index; Using temporary; Using filesort | 
|  1 | SIMPLE      | t     | ref   | screen_name   | screen_name | 17      | func |      2 | Using where                                  | 
+----+-------------+-------+-------+---------------+-------------+---------+------+--------+----------------------------------------------+

Обратите внимание на число 100126 строк, проверенных для сканирования index и ref = func для второй таблицы вприсоединиться к заказу.

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

Схема для этих двух таблиц:

CREATE TABLE `twitter_handle` (
  `handle_id` int(11) NOT NULL AUTO_INCREMENT,
  `handle` varchar(30) CHARACTER SET ascii NOT NULL,
  `twitter_token_id` int(11) DEFAULT NULL,
  `name` varchar(255) CHARACTER SET utf8 DEFAULT NULL,
  `twitter_user_id` int(11) unsigned DEFAULT NULL,
  `location` varchar(100) CHARACTER SET utf8 DEFAULT NULL,
  `profile_image_url` varchar(255) CHARACTER SET utf8 DEFAULT NULL,
  `followers_count` int(11) DEFAULT NULL,
  `twitter_list_id` int(4) DEFAULT NULL,
  `last_update` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `bio` varchar(160) CHARACTER SET utf8 DEFAULT NULL,
  PRIMARY KEY (`handle_id`),
  UNIQUE KEY `handle` (`handle`),
  KEY `twitter_token_id` (`twitter_token_id`),
  KEY `twitter_user_id` (`twitter_user_id`)
) ENGINE=InnoDB;

CREATE TABLE `tweets` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `twitter_id` char(15) DEFAULT NULL,
  `screen_name` varchar(15) NOT NULL,
  `logged_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `text` char(200) NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `status` enum('pending','processed','ignored','pending_delete','deleted','pending_tweet','preview') NOT NULL DEFAULT 'pending',
  `interaction_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `twitter_id_UNIQUE` (`twitter_id`),
  UNIQUE KEY `interaction_id_idx` (`interaction_id`),
  UNIQUE KEY `interaction_id` (`interaction_id`,`status`),
  KEY `screen_name` (`screen_name`,`created_at`),
  KEY `status_2` (`status`,`created_at`),
  KEY `created_at_2` (`created_at`)
) ENGINE=InnoDB;

1 Ответ

0 голосов
/ 07 октября 2010

Причина в том, что дескриптор в twitter_handle - это кодировка ascii, но имя_экранов в твитах - latin1!

...