2013-08-28 3 views
0

У меня есть следующий запрос:Сортировать по замедляет запрос

select 
    `gasr`.`RID`, 
    `gasr`.`ID`, 
    `gr`.`RID`, 
    `gr`.`TID` 
    ... 
from 
    ((((((((((((`gasr` 
    left join `gasro` ON ((`gasr`.`ID` = `gasro`.`ARID`))) 
    left join `gro` ON ((`gro`.`RID` = `gasr`.`RID`))) 
    left join `p` ON ((`p`.`ID` = `gasr`.`ID`))) 
    left join `l` ON ((`l`.`ID` = `p`.`LID`))) 
    left join `k` ON ((`k`.`ID` = `p`.`KID`))) 
    left join `s` ON ((`s`.`ID` = `p`.`TID`))) 
    left join `ad` ON ((`ad`.`ID` = `p`.`DID`))) 
    left join `ae` ON ((`ae`.`ID` = `p`.`EID`))) 
    left join `gr` ON ((`gasr`.`RID` = `gr`.`ID`))) 
    left join `gs` ON ((`gs`.`ID` = `gr`.`SID`))) 
    left join `ka` ON ((`ka`.`ID` = `gs`.`KID`))) 
    left join `m` ON ((`m`.`ID` = `ka`.`MID`))) 
ORDER BY gs.ID, gr.RID 

Который действительно занимает некоторое время (около 5 секунд) при использовании ORDER BY, как описано. Если я не буду использовать ORDER BY, это очень быстро (0,08 секунды).

Объясните мне показывает, что будет временная таблица, созданная: enter image description here

На обоих полях order by части является нормальным индексом (по возрастанию).

В этом проблема? Как я могу избежать этого?

ТИА Matt

ответ

1

frgtv10, я хочу сказать одно слово к вам, только одно слово: FileSort

"The Graduate" цитирует в сторону, тот факт, что вы получили ключи от обоих поля, которые вы сортируете, не означает, что MySQL сможет использовать их для сортировки, и в этом случае это не так. Процитировать MySQL ref's ORDER BY Optimization:

В некоторых случаях MySQL не может использовать индексы для решения ORDER BY, .... Эти случаи включают в себя следующее:

...

  • Вы присоединяетесь много таблиц и столбцов в ORDER BY не все из первой непостоянной таблицы, используемой для извлечения строк. (Это первая таблица в EXPLAIN вывода, который не имеет константный типа соединения.)

Теперь, независимо от того, или нет, это настоящая проблема зависит от применения вашего запроса, в частности, является ли этим конкретным запрос может быть медленным или нет.

Избегание проблемы путем получения этого SELECT + ORDER комбо до скорости даст вам серьезную головную боль, если это вообще возможно. Лично в этом случае я бы пошел на сортировку данных после извлечения, если такое возможно. И снова я бы рекомендовал не использовать более трех или четырех четвертей JOIN s в одном запросе (quick search покажет вам, что многие уже попали в эту проблему на одном JOIN), и поэтому будет искать решение, которое позволяет избежать объединения дуодеков в его целостность.

+0

Благодарим вас за ответ. Каково ваше предложение? Вы говорите, просто доставляете все данные и делаете фильтр/порядок позже на PHP? – frgtv10

+0

Как сказано, это зависит от приложения и его потребности; но да, основываясь на информации, которая будет моим выбором. В то же время, я предлагаю вам сохранить какой-либо поднабор-выбор ('WHERE') в запросе, но выполнять статические сравнения перед агрегацией (т.е. вставлять' JOIN' с 'AND' вместо использования 'late «ГДЕ»). Кроме того, в зависимости от области памяти вашего выбора вы можете захотеть получить список по запросу, содержащему только параметры заказа и идентификаторы, заказать его, а затем запросить дополнительные данные. – vollie

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