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

Форум MySQL

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

 

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

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

тема: Оптимизация запроса. Помогите, кто разбирается.
 
 автор: virtus1k   (18.07.2009 в 14:47)   письмо автору
 
 

Привет. Есть запрос.
Не буду описывать какую выборку он делает. Сейчас дает мне результат тот который нужно, но я думаю, что может можно как-то его укоротить.


SELECT  t3.`idd`,t3.`name`,t1.`iddp`,t2.`name` as `svo`,tab1.idprod, tab1.name
FROM rus_shop_dsc as t1 
LEFT JOIN rus_shop_dspo as t2 ON (t1.`iddp` = t2.`idpo`) 
LEFT JOIN rus_shop_ds as t3 ON (t2.`pidpo` = t3.`idd` AND t3.`poi`='1') 
left join rus_shop_prod as tab1 on (t1.`idprod`=tab1.`idprod`) 
WHERE t3.`idcat`='2' AND t3.`hide`='0' 
AND 
(tab1.idprod IN (SELECT `idprod` from rus_shop_dsc as tab0 WHERE tab0.iddp='1')) 
AND 
(tab1.idprod IN (SELECT `idprod` from rus_shop_dsc as tab0 WHERE tab0.iddp='7')) 
AND 
(tab1.idprod IN (SELECT `idprod` from rus_shop_dsc as tab0 WHERE tab0.iddp='120'))  
ORDER BY t3.`pm`,t3.`name`,t2.`name` ASC



Так, вот, параметров AND (tab1.idprod IN (SELECT...... может быть много.
Хотелось бы оптимизировать запрос. Возможно ли как-то его сократить (имеетвся ввиду именно AND (tab1.idprod IN (SELECT...... )

P.S. если есть вопросы - задавайте.

  Ответить  
 
 автор: Евгений Петров   (20.07.2009 в 22:20)   письмо автору
 
   для: virtus1k   (18.07.2009 в 14:47)
 

Для начала можно написать так:
AND tab1.idprod IN (SELECT `idprod` from rus_shop_dsc as tab0 WHERE tab0.iddp IN (1, 7, 120))

Можно ещё попробовать как то так. Поидее должно работать быстрее.
SELECT
    t3.`idd`,
    t3.`name`,
    t1.`iddp`,
    t2.`name` as `svo`,
    tab1.idprod,
    tab1.name
FROM
    rus_shop_dsc AS t1
LEFT JOIN
    rus_shop_dspo as t2 ON (
        t1.`iddp` = t2.`idpo`
    )
LEFT JOIN
    rus_shop_ds AS t3 ON (
        t2.`pidpo` = t3.`idd`
        AND t3.`poi`='1'
    ) 
LEFT JOIN
    rus_shop_prod AS tab1 ON (
        t1.`idprod` = tab1.`idprod`
    )
INNER JOIN
    rus_shop_dsc AS tab0 ON
        tab0.iddp IN (1, 7, 120)
        AND tab1.idprod = tab0.idprod
WHERE
    t3.`idcat`= '2'
    AND t3.`hide` = '0' 
ORDER BY
    t3.`pm`,
    t3.`name`,
    t2.`name` ASC

Выложите EXPLAIN всех запросов.

  Ответить  
 
 автор: Trianon   (20.07.2009 в 22:37)   письмо автору
 
   для: Евгений Петров   (20.07.2009 в 22:20)
 

>Для начала можно написать так:
>AND tab1.idprod IN (SELECT `idprod` from rus_shop_dsc as tab0 WHERE tab0.iddp IN (1, 7, 120))

Увы... там, похоже, INTERSECT нужен, а в MySQL его нет вроде как.

  Ответить  
 
 автор: Евгений Петров   (20.07.2009 в 23:07)   письмо автору
 
   для: Trianon   (20.07.2009 в 22:37)
 

А, да, зато можно выбрать сначала id-шники одним запросом:
SELECT `idprod` from rus_shop_dsc as tab0 WHERE tab0.iddp IN (1, 7, 120)

если их не очень много а потом сформировать второй запрос подставляя уже готовые значения вместо подзапросов.

  Ответить  
 
 автор: Trianon   (20.07.2009 в 23:26)   письмо автору
 
   для: Евгений Петров   (20.07.2009 в 23:07)
 

Так в том и соль, что idprod'ы нужно брать не те, что есть хотя бы в одном из трех iddp , а те
что встречаются во всех трех одновременно.

  Ответить  
 
 автор: Евгений Петров   (21.07.2009 в 20:01)   письмо автору
 
   для: Trianon   (20.07.2009 в 23:26)
 

Можно выбрать и idprod'ы и iddp'ы одним запросом а потом уже средствами пхп сгруппировать результаты и сформировать конечный sql:

AND tab1.idprod IN (" . join(",", $idprods[1]) . ") 
AND tab1.idprod IN (" . join(",", $idprods[7]) . ") 
AND tab1.idprod IN (" . join(",", $idprods[120]) . ")

  Ответить  
 
 автор: Trianon   (22.07.2009 в 00:31)   письмо автору
 
   для: Евгений Петров   (21.07.2009 в 20:01)
 

Ну тогда уж что мешает array_intersect посчитать на php?

  Ответить  
 
 автор: Евгений Петров   (22.07.2009 в 00:54)   письмо автору
 
   для: Trianon   (22.07.2009 в 00:31)
 

Я же писал - "если данных не очень много". Поэтому и просил EXPLAIN.

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

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