powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Помогите разобраться с AND EXISTS
4 сообщений из 4, страница 1 из 1
Помогите разобраться с AND EXISTS
    #39410761
Евгений57
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть запросы, не понимаю зачем там AND EXISTS и как он работает
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
SELECT attribute_id, text FROM (
SELECT DISTINCT p.product_id, p2a.attribute_id, p2a.text, p.price as realprice 
FROM oc_product p 
LEFT JOIN oc_product_to_store p2s ON (p2s.product_id=p.product_id) 
LEFT JOIN oc_product_to_category p2c ON (p2c.product_id=p.product_id) 
LEFT JOIN oc_category_path cp ON(cp.category_id=p2c.category_id) 
LEFT JOIN oc_product_attribute p2a ON (p2a.product_id=p.product_id) 
WHERE p2a.attribute_id IS NOT NULL AND EXISTS 
(select 1 FROM oc_product_attribute p2a0 
WHERE p2a0.product_id=p2a.product_id AND p2a0.attribute_id = 20 
AND (p2a0.text = '2х36 Вт' OR p2a0.text like '2х36 Вт:%' OR p2a0.text like '%:2х36 Вт' OR p2a0.text like '%:2х36 Вт:%')) 
AND EXISTS (select 1 FROM oc_product_attribute p2a1 WHERE p2a1.product_id=p2a.product_id AND p2a1.attribute_id = 22 
AND (p2a1.text = 'накладные' OR p2a1.text like 'накладные:%' OR p2a1.text like '%:накладные' OR p2a1.text like '%:накладные:%')) 
AND EXISTS (select 1 FROM oc_product_attribute p2a2 WHERE p2a2.product_id=p2a.product_id AND p2a2.attribute_id = 27 
AND (p2a2.text = '120 см' OR p2a2.text like '120 см:%' OR p2a2.text like '%:120 см' OR p2a2.text like '%:120 см:%')) 
AND p.status = '1' AND p2s.store_id = 0) as innertable WHERE 1 GROUP BY attribute_id, text



Хочу его ускорить. правильно ли его будет переписать примерно так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
SELECT attribute_id, text FROM (
SELECT DISTINCT p.product_id, p2a.attribute_id, p2a.text, p.price as realprice 
FROM oc_product p 
LEFT JOIN oc_product_to_store p2s ON (p2s.product_id=p.product_id) 
LEFT JOIN oc_product_to_category p2c ON (p2c.product_id=p.product_id) 
LEFT JOIN oc_category_path cp ON(cp.category_id=p2c.category_id) 
LEFT JOIN oc_product_attribute p2a0 ON (p2a0.product_id=p.product_id)
LEFT JOIN oc_product_attribute p2a1 ON (p2a1.product_id=p.product_id) 
LEFT JOIN oc_product_attribute p2a2 ON (p2a2.product_id=p.product_id) 
WHERE 
p2a0.attribute_id = 20 AND (p2a0.text = '2х36 Вт' OR p2a0.text like '2х36 Вт:%' OR p2a0.text like '%:2х36 Вт' OR p2a0.text like '%:2х36 Вт:%')
AND p2a1.attribute_id = 22 AND (p2a1.text = 'накладные' OR p2a1.text like 'накладные:%' OR p2a1.text like '%:накладные' OR p2a1.text like '%:накладные:%')
AND p2a2.attribute_id = 27 AND (p2a2.text = '120 см' OR p2a2.text like '120 см:%' OR p2a2.text like '%:120 см' OR p2a2.text like '%:120 см:%')
AND p.status = '1' AND p2s.store_id = 0) as innertable WHERE 1 GROUP BY attribute_id, text


По полям p2a0.text есть индекс p2a0.text_id в другой таблице, соответственно хочу чтобы все работало не через поиск по тексту, а через индекс, поэтому в последствии AND (p2a1.text = 'накладные' OR p2a1.text..... Преобразую в AND p2a1.text_id = XXX

И вот тут можно и INNER JOIN написать, ничего я так понимаю не поменяется?
LEFT JOIN oc_product_attribute p2a0 ON (p2a0.product_id=p.product_id)
LEFT JOIN oc_product_attribute p2a1 ON (p2a1.product_id=p.product_id)
LEFT JOIN oc_product_attribute p2a2 ON (p2a2.product_id=p.product_id)
...
Рейтинг: 0 / 0
Помогите разобраться с AND EXISTS
    #39410844
Евгений57
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Переписал вот так, но стало в 2 раза дольше выполняться, хотя результат вроде как верный:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
SELECT SQL_NO_CACHE attribute_id, text FROM (
SELECT DISTINCT p.product_id, p2a.attribute_id, p2a.text, p.price as realprice 
FROM oc_product p 
LEFT JOIN oc_manufacturer m ON(m.manufacturer_id=p.manufacturer_id) 
LEFT JOIN oc_product_option_value pov ON (pov.product_id=p.product_id) 
LEFT JOIN oc_product_to_store p2s ON (p2s.product_id=p.product_id) 
LEFT JOIN oc_product_to_category p2c ON (p2c.product_id=p.product_id) 
LEFT JOIN oc_category_path cp ON(cp.category_id=p2c.category_id) 
LEFT JOIN oc_product_attribute p2a ON (p2a.product_id=p.product_id) 
WHERE p.product_id IN(
SELECT DISTINCT p2a.product_id FROM oc_product_attribute p2a 
LEFT JOIN oc_product_attribute p2a0 ON (p2a0.product_id=p2a.product_id) 
LEFT JOIN oc_product_attribute p2a1 ON (p2a1.product_id=p2a.product_id) 
WHERE (p2a.attribute_id = 20 AND p2a.text like '%2х36 Вт%') 
AND  (p2a0.attribute_id = 22 AND p2a0.text like '%накладные%')
AND  (p2a1.attribute_id = 27 AND p2a1.text like '%120 см%')
) 
) as innertable WHERE 1 GROUP BY attribute_id, text
...
Рейтинг: 0 / 0
Помогите разобраться с AND EXISTS
    #39410852
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Евгений57,

JOIN-ы множат записи в результате, если искомых записей в подсоединяемой таблице более одного.
EXISTS найдет одну запись и упокоится, а JOIN вытащит их все, затем вы из DISTINCT-ом будете сводить обратно в одну.

Кроме того, то версии MySQL 5.6 конструкция IN (SELECT ...) работает очень долго из-за многократного выполнения подзапроса.
И, кстати, DISTINCT внутри него смысла не имеет, но может увеличивать время работы.
...
Рейтинг: 0 / 0
Помогите разобраться с AND EXISTS
    #39410892
Евгений57
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Объясните как это работает:
LEFT JOIN oc_product_attribute p2a ON (p2a.product_id=p.product_id)
WHERE p2a.attribute_id IS NOT NULL AND EXISTS
(select 1 FROM oc_product_attribute p2a0
WHERE p2a0.product_id=p2a.product_id AND p2a0.attribute_id = 20
AND (p2a0.text = '2х36 Вт' OR p2a0.text like '2х36 Вт:%' OR p2a0.text like '%:2х36 Вт' OR p2a0.text like '%:2х36 Вт:%'))

Мы цепляем таблицу p2a у которой attribute_id IS NOT NULL И что????
с одной стороны select 1 то есть результатов выборки нет, точнее одни единицы.
с другой стороны p2a0.product_id=p2a.product_id - цепляет p2a по product_id как-то и плюс условия по text и product_id.

Если WHERE p2a.attribute_id цепляет атрибуты по [select * FROM oc_product_attribute p2a0
WHERE p2a0.product_id=p2a.product_id AND p2a0.attribute_id = 20
AND (p2a0.text = '2х36 Вт' OR p2a0.text like '2х36 Вт:%' OR p2a0.text like '%:2х36 Вт' OR p2a0.text like '%:2х36 Вт:%'))]
то почему не написали просто WHERE p2a.attribute_id IS NOT NULL AND (p2a.attribute_id = 20 OR p2a.attribute_id = 22...)
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Помогите разобраться с AND EXISTS
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]