Je suis très confus pour l'instant, car j'ai deux colonnes indexées sur des tables séparées. L'une des tables, 'users', compte environ 400 000 entrées, et l'autre, 'posts', compte environ 8 000 000 entrées.RoR: Performance des champs indexés
Je sais que ces deux domaines sont indexés, et j'ai confirmé avec mon schéma:
add_index "users", ["username"], :name => "index_users_on_username", :unique => true
add_index "posts", ["tag"], :name => "index_posts_on_tag", :unique => true
Mais en quelque sorte, quand je lance ce qui suit, il faut compter entre 10 et 13 secondes:
User.find_by_username("mickeleh")
et quand je cours essentiellement la même chose sur les messages, cela prend moins d'une seconde!
Post.find_by_tag("En-SKKB67Cg")
Quelqu'un peut-il m'expliquer pourquoi cela pourrait se produire? Et/ou comment pourrais-je faire fonctionner ma méthode User.find_by_username
plus rapidement?
Mise à jour:
j'ai couru une expliquer sur chacun des appels et je me suis le suivant:
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 |
+----+-------------+----------+------+---------------+------+---------+------+--------+-------------+
et
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 | |
+----+-------------+--------+-------+---------------------+---------------------+---------+-------+------+-------+
Je ne sais pas exactement comment lire ce qui a été retourné, donc de l'aide avec être très apprécié.
J'ai aussi créé une nouvelle migration vers « reset » index sur la colonne de nom d'utilisateur des utilisateurs, comme suit:
remove_index :users, :column => :username
add_index :users, :username, :unique => true
ça n'a pas
Je viens de réaliser une chose cela pourrait causer le problème .. La table des utilisateurs a un champ qui est un ensemble sérialisé .. et je ne pense pas que cela causerait le problème. mais je pense que c'est possible.
MISE A JOUR FINAL
Ainsi, pour une raison quelconque, quand j'étais très développeur RoR novice, j'ai décidé que ce serait une bonne idée de remplacer la méthode 'find_by_username' avec le mien qui ferait en sorte qu'il a cherché des noms d'utilisateur ignorant le boîtier.
C'était assez ridicule .. comme je n'avais pas vraiment besoin de modifier la méthode d'origine pour obtenir la même réponse de requêtes différemment encapsulées.
Donc, la morale de l'histoire est de ne pas inclure la méthode suivante dans un modèle ....
def self.find_by_username(name)
User.where("lower(username) = '#{name.downcase}'")[0]
end
- visage paume -
Avez-vous essayé d'exécuter expliquer sur la requête? (dans la console MySQL) –
Je viens de lancer les explications et j'ai mis à jour ma question pour inclure les informations supplémentaires. – BananaNeil