如何有效率地分頁?

Efficient Pagination Using MySQL 是一份針對分頁這件事情如何更快的 PDF。

傳統的分頁方式,正如 will_paginate plugin 所做的:顯示所有頁數跟連結。有個不 scale 的問題是,它用了 OFFSET 跟 COUNT,當資料量越來越多,分頁的速度就會越來越慢 :(


 SELECT count(*) FROM messages
 SELECT * FROM messages ORDER BY id DESC LIMIT 0, 20

這裡提出的解決方案如同 Twitter 所採用的,只讓使用者點下一頁:

不要顯示頁數、不要顯示總數量,可以搭配使用 Ajax 換下一頁。如此就可避免使用到 OFFSET 只用 LIMIT,也減少了一次 COUNT query。


page1 = SELECT * FROM messages LIMIT 10 WHERE id > 0 ASC id
page2_min_id = page1.last.id
page2 = SELECT * FROM messages LIMIT 10 WHERE id > page2_min_id ASC id

當然,有個缺點就是使用者沒辦法知道總共有多少資料了。

Moneta: 提供 key/value stores 的統一介面

今天我想特別介紹這一套 Ruby library: Moneta

它提供了 key-value stores 標準共通的使用介面,讓你可以用相同的程式,但是可以輕易轉換底層實際使用的儲存庫,包括:

  • Basic File Store
  • BerkeleyDB
  • CouchDB
  • DataMapper
  • File store for xattr
  • In-memory store
  • Memcache store
  • Redis
  • S3
  • SDBM
  • Tokyo
  • Xattrs in a file system

它的用法其實跟 Hash API 差不多,非常容易使用。我認為最實際的用途是用在撰寫快取程式了。

因為不同環境可以輕易切換 store 的這個好處,我在 local 的 development 環境中,可以使用 In-memory store 或 File Store (前者重開 server 快取資料就會消失,後者則會留著),不需要多裝東西就可以寫快取。更重要的是,團隊中其他人也不需要費心設定 (叫每個人都去裝 Memcached 也太辛苦了)。而在 production 正式環境中,則可以輕易設定成使用 Memcached

我自己也用了 Moneta 介面寫了一個小程式 Headcache,提供了 get_and_set 功能:


data = Handcache.get_and_set("data-123", :expires_in => 60 ) do
                "cached-foobar"
            end

如果快取存在,就回傳快取資料;如果不存在,就執行 code block,並將最後的運算值回傳並快取起來。

如果是在 View 中搭配 partial 使用也非常簡單:


<%= Handcache.get_and_set( dom_id(@post), :expires_in => 60 ) do
               render :partial => "post"
           end %>

設定的方法則可以是:


# config/environments/development.rb
begin
  # for developer has tokyo cabinet
  Handcache = Moneta::Tyrant.new( :host => 'localhost', :port => 1978 )
rescue
  # for developer has not tokyo cabinet
  Handcache = Moneta::BasicFile.new( :path => "tmp" )
end

關於快取這件事情的學問,可以參考我之前的 Memcached 文章:一是如何清除過期的快取資料(expire),二是注意快取 Key 的命名。

Rails Best Practices Gem: 靜態分析Rails程式碼

Rails Best Practices Gemflyerhzm 根據我的 Rails Best Practices 演講的內容,所作出來的靜態分析程式,可以幫助你快速找到一些可能可以改善的地方。

透過 sudo gem install rails_best_practices –source gemcutter.org 安裝之後,只要執行 rails_best_practices . 就會開始分析你的程式,十分神奇。

這個 gem 也被 Ruby5 – Episode #28Rails Envy Podcast – Episode 102InfoQ China 等介紹。

校園自由工作坊-Ruby 初探 @ 清華大學資工系

Update (2010/12/3): 本活動 12/7 才會開放報名。

又要開課了,和上一回類似的課程內容,這次 OSSF 和清大資工系合辦,時間地點是 12/23 在清華大學 :)

這次真的是大學生了,準備來把範例改成瞇圖程式(?)
anyway,能夠回母校上點課,真是開心 :)