2012-06-13 6 views
2

Этот запрос работает медленно:улучшить производительность Регистрация

SELECT UserAccountNumber, balance, username FROM users JOIN balances ON 
users.UserAccountNumber=balances.UserAccountNumber WHERE date < “2011-02-02” 

Что я могу сделать, чтобы улучшить его работу?

Я думал об использовании идентификатора пользователя для соединения вместо userAccountNumber. Appart сформируйте его, насколько я знаю, JOIN и WHERE users.id = balances.idUser выполняют с той же скоростью ...

Итак, что еще я могу изменить, чтобы улучшить его? Спасибо.

+0

Нам нужна дополнительная информация о вашей схеме. Используете ли вы индексы и внешние ключи? –

+0

Какие у вас есть признаки? Если у вас есть как «userId», так и «userAccountNumber» как в «пользователях», так и «балансах», вы полностью не нормализировали свою настройку, и вы можете вернуться позже, чтобы укусить вас (что произойдет, если они перестанут указывать на то же самое 'пользователь' запись?). –

+0

У меня индексируется UserAccountNumber. Но. не будет ли быстрее иметь другую таблицу с UserAccountNumber и ID, и только здесь, используя идентификатор, чтобы сделать JOIN? Благодарю. – Alvaro

ответ

4

Сам запрос выглядит хорошо для меня, но убедитесь, что у вас есть индексы на столбцах UserAccountNumber (так как они участвуют в объединении) и date (колонка, которую вы ищете). Если база данных должна выполнять последовательное сканирование большого количества записей, это будет медленным. Использование EXPLAIN SELECT может помочь вам понять, как база данных выполняет запрос.

+0

Итак, мне нужно будет также индексировать столбец даты. И ... как насчет использования и UNIXDATE, сохраняя поле DATE как INT? Разве это не быстрее, чем сравнение полей DATE? – Alvaro

+0

Даты, вероятно, уже хранятся как целые числа внутри, поэтому я сомневаюсь, что это изменило бы ситуацию. – Wyzard

0

Если таблицы огромны, вы можете получить некоторые улучшения, используя временную таблицу, а затем позволить оптимизатору MySQL отсортировать его для вас. Хотя это будет компромисс.

CREATE TEMPORARY TABLE `tmp_balances` 
(
    `UserAccountNumber` INT, 
    `balance` INT, 
    INDEX (`UserAccountNumber`) 
) ENGINE=MEMORY 
SELECT `UserAccountNumber`, `balance` 
FROM balances 
WHERE date < "2011-02-02"; 

SELECT `tmp_balances`.`UserAccountNumber`, 
    `tmp_balances`.`balance`, 
    `users`.`username` 
FROM `tmp_balances` INNER JOIN users USING (`UserAccountNumber`); 

Другое то, что (и это немного длинного выстрела), я должен повторить то, что сказал ранее commentors об индексации.

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