的性能,我此刻很困惑,因爲我有不同的表中兩個索引列。其中一個表格'用戶'擁有約400,000個條目,另一個'帖子'具有約8,000,000個條目。回報率:索引字段
我知道這兩個字段建立索引,並且我有我的架構證實了它:
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
方法運行得更快?
更新:
我跑在每個呼叫的解釋,我得到了以下幾點:
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表有一個字段是一個序列化的Set ..我不認爲這會導致問題。但我認爲這是可能的。
最後更新
所以,出於某種原因,當我還是一個非常新手RoR的開發者,我決定將它與替換「find_by_username」的方法是個好主意我自己的,這將確保它搜索用戶名忽略外殼。
這是非常荒謬的。至於我其實沒有需要改變原來的方法從不同的套管查詢同樣的反應。
所以這個故事的寓意是不包括在任何模型下面的方法....
def self.find_by_username(name)
User.where("lower(username) = '#{name.downcase}'")[0]
end
- 臉手掌 -
你試過在查詢上運行解釋嗎? (在MySQL控制檯中) – 2012-01-07 21:54:46
我只是跑瞭解釋,我更新了我的問題以包含額外的信息。 – BananaNeil 2012-01-08 07:15:59