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




MySQL.RU - Webboard



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

> Original message text:
> 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` просто не существовать.
>
> Собственно вопрос - что я делаю неправильно, что он использует временную таблицу и не те индексы (хотя насчет индексов я не уверен)? Как можно оптимизировать этот запрос?
>
> Заранее спасибо.
>


From: pavel - 20/02/2009 - 11:47:44
Subject:оптимизация SELECT для нескольких таблиц
-----------------
Решение найдено - принудительно создается запись с ID=0.

Временная таблица, о которой я говорил, получается в результате SELECT DISTINCT. Я так понимаю что это не побороть вообще никак. Правда в результате добавления записи с ID=0 DISTINCT больше не нужен.


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

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

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



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