|
|
|
| Привет. Есть запрос.
Не буду описывать какую выборку он делает. Сейчас дает мне результат тот который нужно, но я думаю, что может можно как-то его укоротить.
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. если есть вопросы - задавайте. | |
|
|
|
|
|
|
|
для: 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 всех запросов. | |
|
|
|
|
|
|
|
для: Евгений Петров
(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 его нет вроде как. | |
|
|
|
|
|
|
|
для: Trianon
(20.07.2009 в 22:37)
| | А, да, зато можно выбрать сначала id-шники одним запросом:
SELECT `idprod` from rus_shop_dsc as tab0 WHERE tab0.iddp IN (1, 7, 120)
|
если их не очень много а потом сформировать второй запрос подставляя уже готовые значения вместо подзапросов. | |
|
|
|
|
|
|
|
для: Евгений Петров
(20.07.2009 в 23:07)
| | Так в том и соль, что idprod'ы нужно брать не те, что есть хотя бы в одном из трех iddp , а те
что встречаются во всех трех одновременно. | |
|
|
|
|
|
|
|
для: 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]) . ")
|
| |
|
|
|
|
|
|
|
для: Евгений Петров
(21.07.2009 в 20:01)
| | Ну тогда уж что мешает array_intersect посчитать на php? | |
|
|
|
|
|
|
|
для: Trianon
(22.07.2009 в 00:31)
| | Я же писал - "если данных не очень много". Поэтому и просил EXPLAIN. | |
|
|
|