SQLinfo.ru - Все о MySQL

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

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

Вы не зашли.

#1 15.06.2011 11:39:18

makcumka
Участник
Зарегистрирован: 15.06.2011
Сообщений: 1

Как уменьшить время выполнения sql запроса к базе mysql

Есть БД, в ней две таблицы: orders и in
В таблице orders - 89 257 строк, весит 1.7 ГБ
В таблице in - 44 610 строкй, весит 6.1 МБ

Такой запрос выполняется: 49.9315 сек.

SELECT * FROM `orders` AS orders, in AS regions WHERE orders.in = regions.index AND (regions.region = 'ЧЕЛЯБИНСКАЯ ОБЛАСТЬ' OR regions.autonom = 'ЧЕЛЯБИНСКАЯ ОБЛАСТЬ' OR regions.region = 'ТЮМЕНСКАЯ ОБЛАСТЬ' OR regions.autonom = 'ТЮМЕНСКАЯ ОБЛАСТЬ' OR regions.region = 'ХАНТЫ-МАНСИЙСКИЙ-ЮГРА АВТОНОМНЫЙ ОКРУГ' OR regions.autonom = 'ХАНТЫ-МАНСИЙСКИЙ-ЮГРА АВТОНОМНЫЙ ОКРУГ' OR regions.region = 'ЯМАЛО-НЕНЕЦКИЙ АВТОНОМНЫЙ ОКРУГ' OR regions.autonom = 'ЯМАЛО-НЕНЕЦКИЙ АВТОНОМНЫЙ ОКРУГ' OR regions.region = 'СВЕРДЛОВСКАЯ ОБЛАСТЬ' OR regions.autonom = 'СВЕРДЛОВСКАЯ ОБЛАСТЬ' OR regions.region = 'КУРГАНСКАЯ ОБЛАСТЬ' OR regions.autonom = 'КУРГАНСКАЯ ОБЛАСТЬ') AND ((orders.zakaz LIKE '%быт%' OR orders.more LIKE '%быт%') AND (orders.zakaz LIKE '%техник%' OR orders.more LIKE '%техник%')) AND ((orders.status_zakaza LIKE '%Ожидает начала торгов%' OR orders.status_zakaza LIKE '%опубликов%' OR orders.status_zakaza LIKE '%ожидание торгов%' OR orders.status_zakaza LIKE '%идет приём заявок%' OR orders.status_zakaza LIKE '%идут торги%' OR orders.status_zakaza = '') and ((date_torg = date_torg_end AND date_add(date_torg, interval 2 month) >= now()) OR date_torg_end >= now())) ORDER BY `datepubl` DESC LIMIT 0, 50


Почему так долго?? Как можно оптимизировать sql код, чтобы запрос выполнялся не более 10 секунд?

Вот структура таблицы orders:
CREATE TABLE IF NOT EXISTS `orders` (
  `id` int(11) NOT NULL auto_increment,
  `firm` text NOT NULL COMMENT '',
  `zakaz` text NOT NULL COMMENT '',
  `platform` varchar(255) NOT NULL COMMENT '',
  `sposob` varchar(255) NOT NULL COMMENT '',
  `datepubl` datetime NOT NULL COMMENT '',
  `izv` varchar(255) NOT NULL COMMENT '',
  `more` longtext NOT NULL COMMENT '',
  `cena` bigint(20) NOT NULL default '0' COMMENT '',
  `linkmore` varchar(255) NOT NULL COMMENT '',
  `in` varchar(255) default NULL COMMENT '',
  `docs` text NOT NULL COMMENT '',
  `date_torg` datetime NOT NULL COMMENT '',
  `date_torg_end` datetime NOT NULL COMMENT '',
  `date_izm_izv` date NOT NULL COMMENT '',
  `status_zakaza` varchar(255) NOT NULL COMMENT '',
  `okdp` int(11) NOT NULL default '0' COMMENT '',
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=94215 ;


Структура таблицы in:
CREATE TABLE IF NOT EXISTS `in` (
  `index` int(6) NOT NULL,
  `opsname` varchar(255) NOT NULL,
  `opstype` varchar(255) NOT NULL,
  `opssubm` varchar(255) NOT NULL,
  `region` varchar(255) NOT NULL,
  `autonom` varchar(255) NOT NULL,
  `area` varchar(255) NOT NULL,
  `city` varchar(255) NOT NULL,
  `city_1` varchar(255) NOT NULL,
  `actdate` datetime NOT NULL,
  `indexold` int(6) NOT NULL,
  PRIMARY KEY  (`index`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Неактивен

 

#2 15.06.2011 14:57:45

memba
Участник
Зарегистрирован: 11.06.2011
Сообщений: 12

Re: Как уменьшить время выполнения sql запроса к базе mysql

Попробуйте применить конструкцию IN,
Т.е заменить этот кусок: (regions.region = 'ЧЕЛЯБИНСКАЯ ОБЛАСТЬ' OR regions.autonom = 'ЧЕЛЯБИНСКАЯ ОБЛАСТЬ' ... и т.д.

Вообще запрос очень жесткий. Like всякие.

Неактивен

 

#3 21.06.2011 22:42:19

maskaral
Участник
Зарегистрирован: 10.06.2009
Сообщений: 9

Re: Как уменьшить время выполнения sql запроса к базе mysql

1. orders.zakaz LIKE '%техник%' - так не будут использоваться индексы, следовательно mysql просмотрит таблицы несколько раз от начала до конца.
смотрите в сторону Fulltext search.

2. много OR замедляют

3. попробуйте переписать запрос на join-ы и замерьте скорость

4. explain query в помощь

Неактивен

 

#4 21.06.2011 23:14:25

evgeny
Гуру
Зарегистрирован: 04.05.2009
Сообщений: 335

Re: Как уменьшить время выполнения sql запроса к базе mysql

Тут надо по любому переписывать логику приложения.
Тяжело конечно что то придумать не зная самого приложения.

Попробуйте сделать что то типо ...

Всем вашим статусам даём номера.

1 быт
2 техник
3 Ожидает начала торгов
4 опубликов
5 ожидание торгов
6 идет приём заявок
7 идут торги

В таблице orders создать колонку status.
Соответственно при создании новой записи в orders, в поле status добавляем связный статус.

Ну и потом в запросе делаем
orders.status_zakaza in(1,2,3,4,5)

Ну и конечно на все связывающие поля нужны индексы.

Неактивен

 

Board footer

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