[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Limit в подзапросе
Страницы: 1, 2
Kusss
SELECT 
o.*
FROM
`order_product` AS o
WHERE
o.order_id IN (
SELECT id
FROM `order`
WHERE `finish` =0
LIMIT 0,30
)

Ругается
Цитата
#1235 - This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
bestxp
ну думаю стоит обновить MySQL как вариант?
Kusss
Текущая версия MySQL: 5.5
Можно заказать от 5.3 до 5.6
redreem
SELECT 
o.*
FROM
`order_product` AS o
WHERE
o.order_id IN (
select * from (
SELECT id
FROM `order`
WHERE `finish` =0
LIMIT 0,30
) as `id`
)

Kusss
redreem
Спасибо, работает.
twin
А для чего лимит в подзапросе? Это никакой экономии не даст. Особенно когда еще один подзапрос добавили.

Так чем не устроило?
SELECT 
o.*
FROM
`order_product` AS o
WHERE
o.order_id IN (
SELECT id
FROM `order`
WHERE `finish` =0
)
LIMIT 0 , 30


_____________
Если вам недостаточно собственных заблуждений, можно расширить их мнениями экспертов.

Нужно уважать мнение оппонета. Ведь заблуждаться - его святое право.

Настаивал, настаиваю и буду настаивать на своем. На кедровых орешках.

user posted image
Kusss
twin
Твой запрос вернет не 30 заказов , а 30 позиций. Если в заказе будет скажем по 8 позиций, то вернется 4 заказа. Причем один будет не полным.
twin
Понятно. Особо не вникал, потому что я бы изначально так не делал. Ну если только ресурсы не важны. Это очень тяжелый запрос получается. Совсем не такой, как кажется на первый взгляд.

Оптимизировать его лениво, ибо не вижу смысла. Я бы решал двумя атомарными запросами.

Если не в курсе, почему тяжелый запрос, могу рассказать.

_____________
Если вам недостаточно собственных заблуждений, можно расширить их мнениями экспертов.

Нужно уважать мнение оппонета. Ведь заблуждаться - его святое право.

Настаивал, настаиваю и буду настаивать на своем. На кедровых орешках.

user posted image
Kusss
Вроде не долго выполняется
Отображает строки 0 - 29 ( 60 всего, Запрос занял 0.0483 сек.)

Но я все же разбил на 2 запроса.
twin
Наверное таблицы небольшие. Вообще это серьёзная ошибка, делать вложенные запросы такого плана. Они оправданы только в редких случаях, когда не важен ресурс. В админке к примеру. Потому что с листа кажется, что сначала отработает внутренний запрос, потом результат подставится во внешний IN().

На самом деле это не так. Потому и LIMIT не работает.
Интерпретатор преобразует такой запрос к примерно такому виду
SELECT o. * 
FROM `order_product` AS o
WHERE EXISTS (
SELECT 1
FROM `order` AS a
WHERE a.`finish` =0
AND o.order_id = a.id

)
и будет сравнивать все значения o.order_id с a.id. То есть будет выполнено не сложение, а умножение. Причем внешнего на внутренний. Если в таблице `order_product` 1000 строк, а в `order` 50 то будет выполнено не 30 (если была бы возможность лимита или с еще одним запросом, как у redreem), и даже не 50, как без него, а 50000 "внутренних запросов" в худшем случае. Там немного не так, EXISTS прекращает поиск при первом совпадении, но не известно откуда он начнет считать.

Если данных немного, то незаметно. Если много и посещаемость большая - стоит задуматься.
Два разных запроса тут намного выгоднее.

_____________
Если вам недостаточно собственных заблуждений, можно расширить их мнениями экспертов.

Нужно уважать мнение оппонета. Ведь заблуждаться - его святое право.

Настаивал, настаиваю и буду настаивать на своем. На кедровых орешках.

user posted image
icedfox
LEFT JOIN тут разве не подойдет ? или я ошибаюсь ?
twin
А смысл тот же. И механизмы похожи.

_____________
Если вам недостаточно собственных заблуждений, можно расширить их мнениями экспертов.

Нужно уважать мнение оппонета. Ведь заблуждаться - его святое право.

Настаивал, настаиваю и буду настаивать на своем. На кедровых орешках.

user posted image
icedfox
Цитата (twin @ 18.02.2016 - 00:28)
А смысл тот же. И механизмы похожи.

Вот это даже не знал. Я правильно понимаю, что JOIN запросы оправданны с таблицами до 1к значений примерно и лучше бить на несколько разных ?
twin
Всё зависит от условий. Но вообще при highload лучше избегать вложенных и составных запросов. Все таки БД, это самое узкое место приложения.

_____________
Если вам недостаточно собственных заблуждений, можно расширить их мнениями экспертов.

Нужно уважать мнение оппонета. Ведь заблуждаться - его святое право.

Настаивал, настаиваю и буду настаивать на своем. На кедровых орешках.

user posted image
Kusss
Да, это в админке. И обновляется не часто
вот оригинал конструкции, который был
SELECT 
o.order_id AS id, o.number, o.print_num, o.board,
o.id_product, o.size, o.color, p.pol,
ko.date, ko.name,
ac.print , ac.text
FROM
`order_product` AS o
LEFT JOIN
`product` AS p ON p.id = o.id_product
LEFT JOIN
`order` AS ko ON ko.id = o.order_id
LEFT JOIN
`order_comment` AS ac ON ac.id_order = o.order_id
WHERE
o.live = 0 AND
o.order_id IN (
SELECT * FROM
(
SELECT o2.id
FROM `order` AS o2
LEFT JOIN `order_comment` AS ac2 ON ac2.id_order = o2.id
WHERE o2.finish = 0 AND ac2.print >= 1 AND ac2.print < 3
ORDER BY o2.id DESC
LIMIT
$c,$str_index
) AS `id`
)
ORDER BY
o.order_id DESC,
ac.print,
ko.date DESC

стало
SELECT 
o.id, o.date, o.name, o.city,
ac.print , ac.text, ac.date_out
FROM
`order` AS o
LEFT JOIN
`order_comment` AS ac ON ac.id_order = o.id
WHERE
o.finish = 0 AND
ac.print >= 1 AND
ac.print < 3
ORDER BY
o.id DESC
LIMIT

$c,$str_index
и

SELECT
o.order_id AS id, o.number, o.print_num, o.board,
o.id_product, o.size, o.color, p.pol
FROM
`order_product` AS o
LEFT JOIN
`product` AS p ON p.id = o.id_product
WHERE
o.live = 0 AND
o.order_id IN (".implode(',', $select).")
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.