2013-06-26 2 views
1

часть запроса:Могу ли я ускорить этот запрос mysql?

SELECT * FROM `o` WHERE .... 
AND `id` IN  (SELECT DISTINCT `id` FROM `o` WHERE `activity` = '1' AND `date` < '20130310'      ORDER BY `id` ASC) 
AND `id` NOT IN (SELECT DISTINCT `id` FROM `o` WHERE `activity` = '1' AND `date` BETWEEN '20130310' AND '20130329' ORDER BY `id` ASC) 
.... 

Desc: идентификаторы, которые до обладают активностью и между 20130310 и 20130329 оленья кожа имеет активность

1) Могу ли я ускорив этот запрос MySQL?

2) Помогает ли ORDER BY увеличить скорость IN и NOT IN?

+0

нет необходимости использовать заказ команды – bugwheels94

+0

@Ankit у вас есть ссылки на это? – EmRa228

+2

Почему вам нужна ссылка для этого заказа, это команда для сортировки выбранных записей и когда вы используете ее в подзапросе, тогда вам не нужно сортировать выбранную запись. Вы можете попробовать ее самостоятельно, удалив ее, и вы увидите никаких изменений в результатах запроса – bugwheels94

ответ

2

как в() подзапросы, как правило, медленно в MySQL (в leasr до 5.6), то лучше использовать присоединитесь

SELECT * FROM `o` 
LEFT JOIN 
(SELECT `id` AS `idactive` FROM `o` WHERE `activity` = '1' AND `date` BETWEEN '20130310' AND '20130329') as t 
USING `id` 
WHERE `activity` = '1' AND `date` < '20130310' AND `idactive` IS NULL 
0

вы можете сделать это, что

SELECT * FROM `o` WHERE .... 
    AND `id` IN  (SELECT DISTINCT `id` FROM `o` 
        WHERE `activity` = '1' AND `date` < '20130310' 
        ORDER BY `id` ASC) 

вам не нужно второе и потому, что вы уже выбрал date < 20130310 поэтому он не будет выбрать 2013031120130312 ... 20130329

или вы можете просто сделать этот запрос

SELECT * FROM `o` WHERE .... 
    AND `activity` = '1' AND `date` < '20130310' 
    GROUP BY `id` 
    ORDER BY `id` ASC 
0

Если id является основным ключом (как это должно быть), один из ваших двух положений даты, связанные с бесполезна (`date` < '20130310' всегда подразумевает NOT (`date` BETWEEN '20130310' AND '20130329'), что позволяет упростить вещь:

select * 
from o 
where activity = 1 
and date < '20130310' 

В случае id фактически один среди других полей (это ужасно запутанный выбор для имени в этом случае), который ссылается на отдельную таблицу в отношениях 1-n или nm, я предполагаю, что вы ищете идентификаторы, где по крайней мере один имеет активность в диапазоне дат , но никакой новой активности с тех пор. В этом случае ваш запрос может быть упрощена:

SELECT * FROM `o` WHERE .... 
AND `id` IN  (SELECT `id` FROM `o` WHERE `activity` = '1' AND `date` < '20130310') 
AND `id` NOT IN (SELECT `id` FROM `o` WHERE `activity` = '1' AND `date` BETWEEN '20130310' AND '20130329') 

Другими словами, distinct и order by положения являются бессмысленными.

В любом случае, если применимо, обратите внимание также, что поле date должно быть типа date, а не типа varchar.

Смежные вопросы