SQLinfo.ru - Все о MySQL Webew.ru: теория и практика веб-технологий

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 14.11.2011 10:08:13

rbwest
Участник
Зарегистрирован: 30.10.2011
Сообщений: 21

Как правильно расставить индексы (тормоза при больших объемах данных)

Здравствуйте! Есть несколько таблиц, которые объединены в одном запросе. Дампы приведены ниже.

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

И еще - может я как то типы полей неправильно указал? И сами дампы правильно составлены? 

Описываю среду, в которой это все работает. Если в таблице table1 менее 20 тысяч записей то все летает. До 50 тысяч записей - уже тупит, но еще терпимо. При 600 тысячах записей время выполнения запроса составляет 20-25 секунд при отрубленном ORDER BY. Если ORDER BY включить - то можно минут 10 курить, запрос не выполнится.

Ниже дампы и сам запрос


-- Структура таблицы `table1` (`table1`)
CREATE TABLE `table1` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `id_razdel` tinyint(3) unsigned NOT NULL default '0',
  `id_oblast` tinyint(3) unsigned NOT NULL default '0',
  `id_city` tinyint(3) unsigned NOT NULL default '0',
  `id_metro` tinyint(3) unsigned NOT NULL default '0',  
  `price` mediumint(10) NOT NULL default '0',  
  `date_create` date NOT NULL default '0000-00-00',
 
  PRIMARY KEY  (`id`),
) ENGINE=MyISAM DEFAULT CHARSET=utf8;


-- Дамп данных таблицы table1 (`table1`)
 
-- -------------------------------------------------------------
INSERT INTO `table1` VALUES ('1', 1, 10, 139, 1, 4200, '2011-11-14');
INSERT INTO `table1` VALUES ('2', 1, 10, 140, 2, 3200, '2011-11-13');
INSERT INTO `table1` VALUES ('3', 1, 10, 141, 3, 2200, '2011-11-12');

-- Структура таблицы `oblast`

CREATE TABLE `oblast` (
  `id_oblast` smallint(5) unsigned NOT NULL auto_increment,
  `name_oblast` varchar(100) NOT NULL default '',
  `sort` tinyint(3) unsigned NOT NULL default '0',
  PRIMARY KEY  (`id_oblast`),

) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- Дамп данных таблицы `oblast`

INSERT INTO `oblast` VALUES (1, 'Область 1', 2);
INSERT INTO `oblast` VALUES (2, 'Область 1', 2);
INSERT INTO `oblast` VALUES (3, 'Область 1', 2);
INSERT INTO `oblast` VALUES (4, 'Область 1', 2);

-- Структура таблицы `city`

CREATE TABLE `city` (
  `id_city` mediumint(8) unsigned NOT NULL auto_increment,
  `id_parent` smallint(5) unsigned NOT NULL default '0',
  `name_city` varchar(100) NOT NULL default '',
  PRIMARY KEY  (`id_city`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- Дамп данных таблицы `city`

INSERT INTO `city` VALUES (1, 1, 'Город 1');
INSERT INTO `city` VALUES (2, 1, 'Город 2');
INSERT INTO `city` VALUES (3, 1, 'Город 3');

-- Структура таблицы `metro`

CREATE TABLE `metro` (
  `id_metro` mediumint(8) unsigned NOT NULL auto_increment,
  `id_parent` smallint(5) unsigned NOT NULL default '0',
  `name_metro` varchar(100) NOT NULL default '',
  PRIMARY KEY  (`id_metro`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- Дамп данных таблицы `metro`

INSERT INTO `metro` VALUES (1, 1, 'Метро 1');
INSERT INTO `metro` VALUES (2, 1, 'Метро 2');
INSERT INTO `metro` VALUES (3, 1, 'Метро 3');
 




// $razdel = Полученный из формы GET раздела
// $oblast = Полученный из формы GET области
// $city = Полученный из формы GET города
// $metro = Полученный из формы GET метро
// $price_pkv_ot, price_pkv_do = Полученный из формы GET цена от и цена до

$query = "SELECT SQL_CACHE SQL_CALC_FOUND_ROWS t1.id, t1.id_razdel, t1.id_oblast, t1.id_city, t1.id_metro, t1.price, t1.date_create, t2.name_oblast, t3.name_city, t4.name_metro FROM table1 t1
           
           
           JOIN oblast t2 ON t1.id_oblast=t2.id_oblast
           JOIN city t3 ON t1.id_city=t3.id_city
           JOIN metro t4 ON t1.id_metro=t4.id_metro          
           WHERE t1.id_razdel$razdel AND t1.id_oblast$oblast AND t1.id_city$city  AND t1.id_metro$metro
           
           AND t1.price>='$price_pkv_ot' AND t1.price<='$price_pkv_do'
           
           ORDER BY date_create DESC LIMIT 0, 100"
;
 

Отредактированно rbwest (14.11.2011 10:10:14)

Неактивен

 

#2 15.11.2011 06:04:42

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Как правильно расставить индексы (тормоза при больших объемах данных)

Покажите explain запроса на ваших данных.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson