Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Долго выполняется запрос
 
 автор: spellalex   (20.02.2011 в 16:47)   письмо автору
 
 

Занялся тут выборкой синонимов из базы, любезно предоставленной [url="http://mindcollapse.com/blog/177.html"]тут[/url] и сразу затык - запрос выполняется слишком долго. От десяти секунд, если в базе до 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;

  Ответить  
 
 автор: Trianon   (20.02.2011 в 16:53)   письмо автору
 
   для: spellalex   (20.02.2011 в 16:47)
 

индексы бы расставить

  Ответить  
 
 автор: Spellalex   (20.02.2011 в 17:11)   письмо автору
 
   для: Trianon   (20.02.2011 в 16:53)
 

Вы имеете ввиду вот так вот? ;)
SELECT DISTINCT
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 OR b.s_id = c.id)
WHERE a.word='стол'

Всё равно не помогает, запрос выдающий 34 синонима выполняется 10 секунд. :(

  Ответить  
 
 автор: neadekvat   (20.02.2011 в 17:24)   письмо автору
 
   для: Spellalex   (20.02.2011 в 17:11)
 

Не в запросе - а в таблице, в самой структуре.

  Ответить  
 
 автор: Spellalex   (20.02.2011 в 18:17)   письмо автору
 
   для: spellalex   (20.02.2011 в 16:47)
 

После нескольких данных мне советов поступил следующим образом:
1. Добавил индекс в таблицу synonyms.
2. Избавился от множества OR в запросе, переделав его в такой:
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='стол'

  Ответить  
 
 автор: neadekvat   (20.02.2011 в 18:19)   письмо автору
 
   для: Spellalex   (20.02.2011 в 18:17)
 

Покажите, как расставили индексы.

  Ответить  
 
 автор: Spellalex   (20.02.2011 в 18:32)   письмо автору
 
   для: neadekvat   (20.02.2011 в 18:19)
 

ALTER TABLE `synonyms` ADD INDEX ( `w_id` ) 
ALTER TABLE `synonyms` ADD INDEX ( `s_id` ) 

  Ответить  
 
 автор: Trianon   (20.02.2011 в 18:34)   письмо автору
 
   для: Spellalex   (20.02.2011 в 18:32)
 

на поле word индекс не хотите поставить?

  Ответить  
 
 автор: Spellalex   (20.02.2011 в 18:40)   письмо автору
 
   для: Trianon   (20.02.2011 в 18:34)
 

Хмм, добавил - хуже вроде не стало.. А есть смысл? ;)
UPD: Виноват, EXPLAIN показал, что смысл в этом всё-таки есть.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования