http://blog.rocodev.com/posts/13-mysql-subquery-in-rails-3有時候設計RailsApplication時,某些JOIN的語法並不是那麼好寫。(不管是手刻,或者是透過ORM下出來。)所以在Application層(PHPorRails)下兩次SELECT或者是用subquery往往
http://blog.rocodev.com/posts/13-mysql-subquery-in-rails-3
有時候設計RailsApplication時,某些JOIN的語法並不是那麼好寫。(不管是手刻,或者是透過ORM下出來。)
所以在Application層(PHPorRails)下兩次SELECT或者是用subquery往往會變成直覺下的取代方案。
舉個例子,有個功能叫做:我上架的書有被人facvorite的總數量。
一般開發者在不用JOIN的情況下,會寫出這樣的code
book_ids=Book.where(:user_id=>user.id)favorite_count=Favorite.where(:book_id=>book_ids).select("book_id").map(&:book_id).uniq.size
因為你無法知道book_ids怎麼拉出來丟query,只好拉到Application層再塞回去用IN撈。數量小這樣的作法是還okay….但…萬一book_ids多達萬,顯然這招就效了。除了慢之外,還製造一堆無用物件浪費記憶體空間…
而Rails3背後強大的Arel,其實提供了自動算出subquery的語法:
其實上面那一段可以改為這樣寫
favorite_count=Favorite.where(:book_id=>Book.where(:user_id=>user.id)).select("distinctbook_id").count
是的,在查詢語句裡面再下條件就會自動變成subquery了....
Favorite.where(:book_id=>Book.where(:user_id=>user.id))
http://stackoverflow.com/questions/5483407/subqueries-in-activerecord幾個原則不是JOIN就是慢兩個SELECT不一定比JOIN快。(在以上book_id數量很大的case中)兩個SELECT有時候會比JOIN快。(在以上book_id數量很小的case中)有時候應該用SUBQUERY取代兩個SELECTSUBQUERY不是萬靈丹,因為大多時候JOIN蠻多時候比SUBQUERY有效率,但SUBQUERY好寫蠻多的,可偷吃步…SUBQUERY適可而止,太多層SUBQUERY效能掉很兇(兩層其實就慢了...)。
原文地址:Rails3中生MySQLsubquery的秘技,感谢原作者分享。