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

Форум MySQL

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

 

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

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

тема: Нужна помощь с оптимизацией JOIN
 
 автор: adebizi   (02.12.2011 в 13:46)   письмо автору
 
 

EXPLAIN SELECT звездочка 
FROM obyav
JOIN company ON obyav.catalog =  '3'
AND obyav.top IS NULL 
AND company.id_news = obyav.id_company
AND TYPE =  '2'
AND obyav.offob =0
AND company.region =  '1'
ORDER BY obyav.date DESC 
LIMIT 0 , 30


id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
1    SIMPLE    obyav    ALL    NULL    NULL    NULL    NULL    764    Using where; Using filesort
1    SIMPLE    company    eq_ref    PRIMARY    PRIMARY    4    de.obyav.id_company    1    Using where



помогите оптимизировать запрос, на мой взгляд что-то с таблицей obyav нужно сделать

  Ответить  
 
 автор: cheops   (02.12.2011 в 13:52)   письмо автору
 
   для: adebizi   (02.12.2011 в 13:46)
 

А можно увидеть структуру таблицы obyav (SHOW CREATE TABLE), да и company тоже? У вас там индексы какие-то есть?

  Ответить  
 
 автор: adebizi   (02.12.2011 в 14:15)   письмо автору
 
   для: cheops   (02.12.2011 в 13:52)
 

obyav    CREATE TABLE `obyav` (
 `id_obyav` int(11) NOT NULL AUTO_INCREMENT,
 `id_company` tinytext,
 `title` tinytext,
 `type` tinytext,
 `info` text,
 `logo` tinytext,
 `cena` tinytext,
 `catalog` tinytext,
 `name_catalog` tinytext,
 `logname` int(11) DEFAULT NULL,
 `date` date DEFAULT NULL,
 `top` tinytext,
 `time` tinytext NOT NULL,
 `offob` tinyint(4) NOT NULL,
 PRIMARY KEY (`id_obyav`)
) ENGINE=MyISAM AUTO_INCREMENT=1516 DEFAULT CHARSET=cp1251



Table    Create Table
company    CREATE TABLE `company` (
 `id_news` int(11) NOT NULL AUTO_INCREMENT,
 `company` tinytext,
 `info` text,
 `rating` int(11) DEFAULT NULL,
 `logo` tinytext,
 `adress` tinytext,
 `telephone` tinytext,
 `mail` tinytext,
 `site` tinytext,
 `face` tinytext,
 `price` tinytext,
 `region` tinytext,
 `logname` int(11) DEFAULT NULL,
 `date` tinytext,
 `top` tinytext,
 `click` int(11) DEFAULT NULL,
 `todayclick` int(11) DEFAULT NULL,
 `dataclick` tinytext,
 `message` tinytext,
 `mailto` tinytext NOT NULL,
 `procom` tinytext,
 PRIMARY KEY (`id_news`)
) ENGINE=MyISAM AUTO_INCREMENT=519 DEFAULT CHARSET=cp1251>

  Ответить  
 
 автор: cheops   (02.12.2011 в 14:19)   письмо автору
 
   для: adebizi   (02.12.2011 в 14:15)
 

Если поставить условие company.id_news = obyav.id_company первым отчет EXPLAIN не меняется?

  Ответить  
 
 автор: adebizi   (02.12.2011 в 15:00)   письмо автору
 
   для: cheops   (02.12.2011 в 14:19)
 

>Если поставить условие company.id_news = obyav.id_company первым отчет EXPLAIN не меняется?

все так же

  Ответить  
 
 автор: cheops   (02.12.2011 в 15:02)   письмо автору
 
   для: adebizi   (02.12.2011 в 15:00)
 

Временно перенесите все условия в WHERE, оставьте только company.id_news = obyav.id_company в ON - ситуация не меняется?

  Ответить  
 
 автор: adebizi   (02.12.2011 в 15:17)   письмо автору
 
   для: cheops   (02.12.2011 в 15:02)
 

>Временно перенесите все условия в WHERE, оставьте только company.id_news = obyav.id_company в ON - ситуация не меняется?

EXPLAIN SELECT * 
FROM (
obyav
LEFT JOIN company ON company.id_news = obyav.id_company
)
WHERE obyav.catalog =  '3'
AND obyav.top IS NULL 
AND TYPE =  '2'
AND obyav.offob =0
AND company.region =  '1'
ORDER BY obyav.date DESC 
LIMIT 0 , 30


все остается по прежнему (

  Ответить  
 
 автор: cheops   (02.12.2011 в 15:29)   письмо автору
 
   для: adebizi   (02.12.2011 в 15:17)
 

Ага не заметил, что у вас obyav.id_company не первичный ключ. Проиндексируйте его (пусть пока все дополнительные условия находятся в WHERE). Индекс по одному столбцу, не уникальный.

  Ответить  
 
 автор: adebizi   (02.12.2011 в 15:52)   письмо автору
 
   для: cheops   (02.12.2011 в 15:29)
 

>Ага не заметил, что у вас obyav.id_company не первичный ключ. Проиндексируйте его (пусть пока все дополнительные условия находятся в WHERE). Индекс по одному столбцу, не уникальный.

не понял, как его проиндексировать ?

  Ответить  
 
 автор: adebizi   (02.12.2011 в 16:00)   письмо автору
 
   для: adebizi   (02.12.2011 в 15:52)
 

аа сейчас поставлю в таблице obyav полю id_company тип int

  Ответить  
 
 автор: cheops   (02.12.2011 в 16:02)   письмо автору
 
   для: adebizi   (02.12.2011 в 16:00)
 

Это самом собой, но еще нужно проиндексировать.

  Ответить  
 
 автор: adebizi   (02.12.2011 в 16:13)   письмо автору
 
   для: cheops   (02.12.2011 в 16:02)
 

>Это самом собой, но еще нужно проиндексировать.

добавил ключ к полю id_company


id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
1    SIMPLE    obyav_copy    ALL    id_company    NULL    NULL    NULL    770    Using where; Using filesort
1    SIMPLE    company    eq_ref    PRIMARY    PRIMARY    4    depoportru.obyav_copy.id_company    1    Using where


все правильно сделал?

  Ответить  
 
 автор: cheops   (02.12.2011 в 16:29)   письмо автору
 
   для: adebizi   (02.12.2011 в 16:13)
 

Да, но индекс все-равно не используется. Попробуйте следующий запрос, что он возвращает?
  EXPLAIN SELECT *  
  FROM 
    (SELECT * FROM obyav
     WHERE
       catalog = '3' AND
       top IS NULL AND
       TYPE =  '2' AND
       offob = 0) AS ob
  LEFT JOIN
    (SELECT * FROM company
     WHERE region =  '1') AS cp
  ON
     cp.id_news = ob.id_company 
  ORDER BY
     ob.date DESC

PS В таблице company сделайте числовым и проиндексируйте поле region

  Ответить  
 
 автор: adebizi   (02.12.2011 в 17:36)   письмо автору
 
   для: cheops   (02.12.2011 в 16:29)
 

id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
1    PRIMARY    <derived2>    ALL    NULL    NULL    NULL    NULL    12    Using temporary; Using filesort
1    PRIMARY    <derived3>    ALL    NULL    NULL    NULL    NULL    5    
3    DERIVED    company    ALL    NULL    NULL    NULL    NULL    474    Using where
2    DERIVED    obyav    ALL    NULL    NULL    NULL    NULL    770    Using where

  Ответить  
 
 автор: cheops   (02.12.2011 в 18:42)   письмо автору
 
   для: adebizi   (02.12.2011 в 17:36)
 

Следующий этап, это оптимизировать внутренние запросы, которые 2 и 3 помечены, нужно добиться, чтобы там использовались ключи. От LEFT JOIN можно отстать, у вас в одной промежуточной таблице 5 строк, в другой 12 и связь по первичному ключу - это нагрузки не создаст. А вот промежуточные таблицы формируются перелопачиванием 474 и 700 записей, чтобы ускорить, нужно задействовать индексы.

Правда при построении дополнительных индексов на все случаи жизни следует иметь в виду: вы увеличиваете размер базы данных, вы ускоряете SELECT, но замедляете INSERT/UPDATE/DELETE (которые и так шибкой скоростью не отличаются). 474 + 700 записей - это не так много, вот 474 * 700 - это много и может отправится на жесткий диск, а не анализироваться в оперативной памяти. В общем продолжать дальше оптимизировать или нет - решать вам, кроме того, без замеров скорости это не очень продуктивное занятие: факторов много, нужна обратная связь, иначе можно запросто замедлить запросы.

PS Откровенно говоря, на 1000 с гаком записей у вас не должно быть никаких проблем, когда это значение увеличиться на порядки - они могут возникнуть, но тогда и следует их решать, заранее просчитать все - практически не реально. Кроме того, не известно, какие запросы у вас будут выполняться чаще - может этот, а может совсем другой, для которого потребуются другие индексы. В общем я бы пока остановился, пока база не подрастет.

  Ответить  
 
 автор: cheops   (02.12.2011 в 16:22)   письмо автору
 
   для: adebizi   (02.12.2011 в 14:15)
 

>`catalog` tinytext,
Кстати, у вас тут тоже только цифры храняться?

PS Все такие поля лучше сделать числовыми - будет гораздо быстрее.

  Ответить  
 
 автор: adebizi   (05.12.2011 в 15:00)   письмо автору
 
   для: cheops   (02.12.2011 в 16:22)
 

>>`catalog` tinytext,
>Кстати, у вас тут тоже только цифры храняться?
>
>PS Все такие поля лучше сделать числовыми - будет гораздо быстрее.

Спасибо за полезные советы, сейчас оптимизирую таблицы.

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

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