Новости
Документация
Download
Webboard
Поиск
FAQ/ЧаВо
Обратная связь




MySQL.RU - Webboard



Вернуться
оптимизация SELECT для нескольких таблиц (Pavel) 11/02/2009 - 19:25:58
      Re: оптимизация SELECT для нескольких таблиц (pavel) 20/02/2009 - 11:47:44



From: Pavel - 11/02/2009 - 19:25:58
Subject:оптимизация SELECT для нескольких таблиц
-----------------
Добрый день,
Суть задачи - оптимизировать запрос из двух таблиц, чтобы он выполнялся как можно быстрее. Но есть некоторое ограничение, в одной из таблиц может не существовать требуемых записей. Итак по-порядку.

Есть две таблицы characters и messages:
CREATE TABLE IF NOT EXISTS `characters` (
`id` bigint(20) NOT NULL auto_increment,
`type` smallint(6) NOT NULL default '0',
`kind` tinyint(4) NOT NULL default '0',
`AI` smallint(6) NOT NULL default '0',
`user_id` bigint(20) default NULL,
`name` varchar(100) collate utf8_bin default NULL,
`updated` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`EP_updated` timestamp NOT NULL default '0000-00-00 00:00:00',
`HP_updated` timestamp NOT NULL default '0000-00-00 00:00:00',
`MP_updated` timestamp NOT NULL default '0000-00-00 00:00:00',
`experience` bigint(20) NOT NULL default '0',
`experience2` bigint(20) NOT NULL,
`power` smallint(6) default '0',
`dexterity` smallint(6) default '0',
`intuition` smallint(6) default '0',
`wisdom` smallint(6) default '0',
`constitution` smallint(6) default '0',
`intellect` smallint(6) default '0',
`icon180` varchar(255) collate utf8_bin default NULL,
`ap` smallint(6) default '6',
`sp` smallint(6) default '0',
`ep` bigint(20) default '2000',
`hp2` int(11) default '0',
`mp2` int(11) default '0',
`stats` smallint(6) default '0',
`location` bigint(20) NOT NULL default '1',
`region` bigint(20) NOT NULL default '1',
`locX` int(11) NOT NULL,
`locY` int(11) NOT NULL,
`coins` bigint(20) NOT NULL default '50',
`gcoins` bigint(20) NOT NULL,
`online` tinyint(4) NOT NULL default '0',
`state` tinyint(4) NOT NULL default '0',
`immunity` tinyint(4) NOT NULL default '0',
`winner` bigint(20) NOT NULL default '0',
`loser` bigint(20) NOT NULL default '0',
`draw` bigint(20) NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=84641 DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=84641 ;

CREATE TABLE IF NOT EXISTS `messages` (
`time` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`message` char(255) collate utf8_bin default NULL,
`channel` int(11) NOT NULL default '0',
`sender` bigint(20) NOT NULL default '0',
`reciever` bigint(20) NOT NULL default '0',
KEY `time` (`time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

Связи:
`mesasges`.`sender` -> `characters`.`id`
`messages`.`.reciever` -> `characters`.`id`

Сам запрос:
SELECT DISTINCT IF (`messages`.`sender`=0, NULL, `characters`.`name`) AS `name`, `messages`.`message`, `messages`.`channel`, `messages`.`reciever` FROM `messages`, `characters` WHERE (`messages`.`sender` != 12 AND IF (`messages`.`sender` != 0, `messages`.`sender` = `characters`.`id`, 1) AND (`messages`.`reciever` IN (0, 12)) AND `messages`.`time` > FROM_UNIXTIME(1234369001))

EXPLAIN этого запроса выдает что используется временная таблица:

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE messages range time,sender,reciever time 4 NULL 1 Using where; Using temporary
1 SIMPLE characters ALL NULL NULL NULL NULL 9 Using where

Основная задача запроса: получить список сообщений для заданного пользователя (`messages`.`reciever` = 12 или 0 (сообщение для всех)), имя отправителя и другую информацию.
Ограничение: id отправителя может быть равно 0 (системное сообщение), и, соответственно, такой записи в таблице `characters` просто не существовать.

Собственно вопрос - что я делаю неправильно, что он использует временную таблицу и не те индексы (хотя насчет индексов я не уверен)? Как можно оптимизировать этот запрос?

Заранее спасибо.


[Это сообщение - спам!]

Последние сообщения из форума

Уважаемые посетители форума MySQL.RU!
Убедительная просьба, прежде чем задавать свой вопрос в этом форуме, обратите внимание на разделы:
- ответы на наиболее часто задаваемые вопросы - FAQ
- раздел документация
- раздел поиск по сообщениям форума и документации
Также, старайтесь наиболее подробно указывать свою ситуацию (версию операционной системы, версию MySQL, версию программного обеспечения, по которому возникает вопрос, текст возникающих ошибок, и др.)
Помните, чем конкретнее Вы опишете ситуацию, тем больше шансов получить реальную помощь.
 Имя:
 E-mail:
 Тема:
 Текст:
Код подтверждения отправки: Code
35034



РЕКЛАМА НА САЙТЕ
  Создание сайтов | |