2012-03-28 3 views
0

У нас есть база данных системы регистрации, и в основном этот запрос выполняется, проверяя учащихся, которые находятся в классе, чтобы они могли быть отмечены как отсутствующие, если они отсутствуют. По какой-то причине это занимает 30 секунд. Кто-нибудь знает, почему?Запрос занимает 30 секунд

FROM Stdts 
    LEFT JOIN StdtReg ON StdtReg.StdtID = Stdts.ID 
    LEFT JOIN usrs ON StdtReg.userID = usrs.ID 
    WHERE (SELECT ID FROM ClssInstncEnrol cie WHERE cie.status = 0 AND classInstanceID={$_GET['ci']} AND StdtID = Stdts.ID LIMIT 1) IS NOT NULL 
    OR (SELECT ID FROM DropIns di WHERE di.type <> -1 AND classInstanceID= {$_GET['ci']} AND StdtID = Stdts.ID LIMIT 1) IS NOT NULL 
    AND (CONCAT(Stdts.firstName, ' ', Stdts.lastName) OR CONCAT(usrs.firstName,' ', usrs.lastName)) 
    ORDER BY firstName, lastName 
+5

Подзапросы, вычисления (CONCAT) на каждой строке, и я бы поставил и недостаточные индексы. – ceejayoz

+1

Попробуйте выполнить «объяснение» в запросе и посмотрите, какие индексы (если они есть) используются. –

+7

Этот код должен занять нулевые секунды и сразу же вызвать ошибку, поскольку это недействительный запрос :) –

ответ

1

Выполните запрос с «EXPLAIN» перед ним, и он расскажет вам, как каждая вкладка le соединяется и где вам может быть недостает индекса.

Кроме того, у вас есть SQL-инъекция, ожидающая появления запросов этой формы с параметрами HTTP, интерполированными непосредственно в запросе.

Наконец, вы отказались от некоторых запросов и схемы, но это ставит меня как нечто, что можно сделать с помощью объединений, а не с подзапросами, или даже в виде отдельных запросов для более эффективного генерации списка идентификаторов учащихся до вы даже запускаете основной запрос.

+0

Это было мое решение , Мне все равно придется вставить mysql_real_escape_string, но на данный момент я действительно не использую функцию поиска в этом запросе. Это было главным образом из-за размера таблицы (более 5000 строк), почему старый запрос был настолько медленным. Когда я тестировал его только с несколькими строками в тестовой среде, это было быстро. Вот что я придумал, это очень быстро. Там могут быть некоторые ошибки, но он отлично работает. – user495216

+0

ВЫБОР Stdts.ID КАК studentID, Stdts.firstName, Stdts.lastName, \t \t \t \t \t \t usrs.firstName, как ufirstname, usrs.LastName в ulastname, \t \t \t \t \t \t usrs.email1 как электронная почта, usrs.homePhone как дома \t \t ОТ Stdts \t \t LEFT JOIN StdtReg ON StdtReg.StudentID = Stdts.ID \t \t LEFT JOIN usrs ON StdtReg. = идентификатор пользователя usrs.ID \t \t LEFT JOIN ClssInstncEnrol CIE ПО Stdts.ID = cie.studentID \t \t ГДЕ ( \t \t \t cie.cl assInstanceID = {$ _GET [ 'CI']} \t \t) \t \t И (CONCAT (Stdts.firstName, '', Stdts.lastName) LIKE '% $ S%' ИЛИ ​​CONCAT (usrs.firstName,»», usrs.lastName) LIKE '% $ S%') \t \t GROUP BY Stdts.ID \t \t ORDER BY FirstName, LastName – user495216

+0

похоже, он потерял все форматирование, так что очень трудно читать. Сожалею. – user495216

0

Попытка проверить план выполнения запроса, чтобы увидеть, что может быть неправильно (если у вас есть огромные таблицы и не использовать соответствующий индекс может быть долго)

0

Может быть, это:

AND (CONCAT(Stdts.firstName, ' ', Stdts.lastName) OR CONCAT(usrs.firstName,' ', usrs.lastName)) 

должно быть:

AND (CONCAT(Stdts.firstName, ' ', Stdts.lastName) = CONCAT(usrs.firstName,' ', usrs.lastName)) 
+1

Не говоря уже о том, есть ли причина для совместного использования двух, а не просто сравнения их непосредственно (firstname = firstname, lastname = lastname)? – Amber

+0

Да, это было бы более разумно. Но конкат-вещь может быть исправлена ​​для неправильных записей (где одно из двух полей содержит полное имя). Хотя, в этом случае я бы попробовал их сначала. – wildplasser

+0

Извините за путаницу. Я оставил часть этого запроса при тестировании и забыл добавить его снова. Возможно, это была путаница с причудой. Вот исходная последняя строка, содержащая LIKE и строку поиска, которые, как мне известно, должны выполняться с помощью mysql_real_escape_string.
И (CONCAT (Stdts.firstName, '', Stdts.lastName) LIKE '% $ s%' ИЛИ ​​CONCAT (usrs.firstName, '', usrs.lastName) LIKE '% $ s%') – user495216

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