Я очень смущен в данный момент, потому что у меня есть два индексированных столбца на отдельных таблицах. Одна из таблиц «пользователи» имеет около 400 000 записей, а другая «сообщения» содержит около 8 000 000 записей.RoR: Производительность индексированных полей
Я знаю, что эти два поля индексируются, и я подтвердил это с моей схемой:
add_index "users", ["username"], :name => "index_users_on_username", :unique => true
add_index "posts", ["tag"], :name => "index_posts_on_tag", :unique => true
Но как-то, когда я бегом следующего, это занимает от 10 до 13 секунд:
User.find_by_username("mickeleh")
, и когда я запускаю по существу то же самое на стойках, это занимает меньше секунды!
Post.find_by_tag("En-SKKB67Cg")
Может кто-нибудь объяснить мне, почему это может произойти? И как я мог бы сделать мой метод User.find_by_username
быстрее?
Update:
я запустил объяснить на каждом из вызовов, и я получил следующее:
mysql> explain SELECT `users`.* FROM `users` WHERE (lower(username) = 'mickeleh');
+----+-------------+----------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+---------------+------+---------+------+--------+-------------+
| 1 | SIMPLE | users | ALL | NULL | NULL | NULL | NULL | 304548 | Using where |
+----+-------------+----------+------+---------------+------+---------+------+--------+-------------+
и
mysql> explain SELECT `posts`.* FROM `posts` WHERE `posts`.`tag` = 'En-SKKB67Cg' LIMIT 1;
+----+-------------+--------+-------+---------------------+---------------------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+-------+---------------------+---------------------+---------+-------+------+-------+
| 1 | SIMPLE | posts | const | index_posts_on_tag | index_posts_on_tag | 258 | const | 1 | |
+----+-------------+--------+-------+---------------------+---------------------+---------+-------+------+-------+
Я точно не знаю, как прочитайте, что было возвращено, так что некоторые из них помогут вам высоко ценить.
Я также создал новую миграцию в «перезагрузки» индексов на поле пользователя пользователей следующим образом:
remove_index :users, :column => :username
add_index :users, :username, :unique => true
он не работает
Я только что понял еще одну вещь это может вызвать проблему. В таблице users есть поле, которое представляет собой сериализованный набор. И я не думаю, что это вызовет проблему. но я считаю, что это возможно.
FINAL UPDATE
Так, по какой-то причине, когда я был в очень начинающий RoR разработчик, я решил, что это было бы хорошей идеей, чтобы заменить метод «find_by_username» с мой собственный, который бы удостоверился, что он искал имена пользователей, игнорируя корпус.
Это было довольно смешно .. поскольку на самом деле мне не нужно было изменять оригинальный метод, чтобы получить тот же ответ от по-разному опрашиваемых запросов.
Итак, мораль этой истории не включает следующий метод в любую модель ....
def self.find_by_username(name)
User.where("lower(username) = '#{name.downcase}'")[0]
end
- лицо ладонь -
Вы попробовали запустить объяснение по запросу? (в консоли MySQL) –
Я только что объяснил, и я обновил свой вопрос, чтобы добавить дополнительную информацию. – BananaNeil