SQLinfo.ru - Все о MySQL

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

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

Вы не зашли.

#1 20.02.2011 16:54:17

Spellalex
Участник
Зарегистрирован: 25.01.2011
Сообщений: 6

Долго выполняется запрос

Занялся тут выборкой синонимов из базы, любезно предоставленной тут и сразу затык - запрос выполняется слишком долго. От десяти секунд, если в базе до 20 синонимов; иногда завершения выборки мне так и не удавалось дождаться. Что тут можно оптимизировать? Сам запрос:

SELECT DISTINCT
c.word
FROM words a
LEFT JOIN synonyms b on (a.id = b.w_id OR a.id = b.s_id)
LEFT JOIN words c on (b.w_id = c.id OR b.s_id = c.id)
WHERE a.word='часы'

Сами таблички выглядят так:
CREATE TABLE `words` (
  `id` int(11) NOT NULL auto_increment,
  `word` varchar(255) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `id` (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=193410 DEFAULT CHARSET=cp1251;
CREATE TABLE `synonyms` (
  `w_id` int(11) NOT NULL,
  `s_id` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=cp1251 PACK_KEYS=0;

Неактивен

 

#2 20.02.2011 16:59:46

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Долго выполняется запрос

1. Уберите OR и DISTINCT. Сделайте два запроса
2. Добавьте KEY(w_id) и KEY(s_id) в таблицу synonyms

Неактивен

 

#3 20.02.2011 17:33:42

Spellalex
Участник
Зарегистрирован: 25.01.2011
Сообщений: 6

Re: Долго выполняется запрос

Спасибо за ответ! Добавил индексы в таблицу synonyms. Вообщем следущим запросом теперь гораздо быстрее происходит выборка (тот же запрос на 30 синонимов теперь выполняется за 0.28 сек.):

SELECT
c.word
FROM words a USE INDEX(primary)
LEFT JOIN synonyms b USE INDEX(w_id, s_id) on (a.id = b.w_id OR a.id = b.s_id)
LEFT JOIN words c USE INDEX(primary) on (b.s_id = c.id)
WHERE a.word='часики'
UNION
SELECT
c.word
FROM words a USE INDEX(primary)
LEFT JOIN synonyms b USE INDEX(w_id, s_id) on (a.id = b.w_id OR a.id = b.s_id)
LEFT JOIN words c USE INDEX(primary) on (b.w_id = c.id)
WHERE a.word='часики'

Вопрос такой, не переусердствовал я с USE INDEX? wink Может быть где его не нужно было указывать?

Неактивен

 

#4 20.02.2011 17:42:58

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Долго выполняется запрос

Остался один реликтовый OR - его тоже нужно убрать.

(a.id = b.w_id OR a.id = b.s_id)
замените на
(a.id = b.w_id)


Попробуйте без USE INDEX и посмотрите как будет работать с помощью EXPLAIN. В большинстве случаев USE INDEX никак не повлияет на запрос.

Неактивен

 

#5 20.02.2011 18:15:33

Spellalex
Участник
Зарегистрирован: 25.01.2011
Сообщений: 6

Re: Долго выполняется запрос

Да, EXPLAIN показал что разницы никакой нет. Спасибо за помощь!
Итоговый запрос у меня выглядит так:

SELECT
c.word
FROM words a
LEFT JOIN synonyms b on (a.id = b.w_id)
LEFT JOIN words c on (c.id = b.s_id)
WHERE a.word='стол'
UNION
SELECT
c.word
FROM words a
LEFT JOIN synonyms b on (a.id = b.s_id)
LEFT JOIN words c on (c.id = b.w_id)
WHERE a.word='стол'

Неактивен

 

Board footer

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