@vgray

Как поправить запрос, чтобы использовались индексы?

Есть две таблицы
CREATE TABLE `ls_topic` (
  `topic_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `topic_title` varchar(200) NOT NULL,
  `topic_publish` tinyint(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`topic_id`),
  KEY `topic_publish` (`topic_publish`),
) ENGINE=InnoDB AUTO_INCREMENT=4340 DEFAULT CHARSET=utf8 

CREATE TABLE `ls_vote` (
  `target_id` int(11) unsigned NOT NULL DEFAULT '0',
  `target_type` enum('topic','blog','user','comment','store') NOT NULL DEFAULT 'topic',
  `user_voter_id` int(11) unsigned NOT NULL,
  `vote_direction` tinyint(2) DEFAULT '0',
  `vote_value` float(9,3) NOT NULL DEFAULT '0.000',
  `vote_date` datetime NOT NULL,
  PRIMARY KEY (`target_id`,`target_type`,`user_voter_id`),
  KEY `user_voter_id` (`user_voter_id`),
  KEY `vote_date` (`vote_date`),
  KEY `target_id` (`target_id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8


Если я делаю запрос только из таблицы ls_vote , то mysql использует индекс таблицы ls_vote и все хорошо.
explain select 
				v.vote_date
				from ls_vote as v

				where
					v.target_type = 'topic' order by v.vote_date desc LIMIT 0,25

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: v
         type: index
possible_keys: NULL
          key: vote_date
      key_len: 8
          ref: NULL
         rows: 25
        Extra: Using where; Using index


но как только я начинаю делать join с таблицей ls_topic, так почему-то для таблицы ls_topic делается выборка всех строк и запрос выполняется несколько секунд
explain select 
				t.topic_id,
				v.vote_date
				from ls_vote as v

				join ls_topic as t
					on (t.topic_id = v.target_id)

				where
					v.target_type = 'topic' order by v.vote_date desc LIMIT 0,25

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t
         type: index
possible_keys: PRIMARY
          key: topic_publish
      key_len: 1
          ref: NULL
         rows: 3733
        Extra: Using index; Using temporary; Using filesort
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: v
         type: ref
possible_keys: PRIMARY,target_id
          key: PRIMARY
      key_len: 5
          ref: t.topic_id,const
         rows: 1
        Extra: Using where
2 rows in set (0.00 sec)


Эти данные я получил на тестовой таблице в которой (3733 записи) в реальной таблице все тоже самое, только там около 40 тыс записей в таблице ls_topic и около 4М записей в таблице ls_vote

Почему база делает полную выборку из таблицы ls_topic? и как это исправить?
  • Вопрос задан
  • 168 просмотров
Пригласить эксперта
Ответы на вопрос 2
@res2001
Developer, ex-admin
А на реальной базе план выполнения такой же? Просто возможно, что по какой-либо причине в данной ситуации на данном наборе записей mysql решил индекс не использовать.
На реальной базе план может быть другой.
И сделайте по topic_id уникальный кластерный индекс.
Ответ написан
Комментировать
@vgray Автор вопроса
да, на реальной базе тоже такой план.

>И сделайте по topic_id уникальный кластерный индекс.
а это как?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы