MySQL 5.1.26

5.1.26-rc 放出來了:。這個版本會是 5.1 最後一個 RC (Release Candicate),下一個就會是 Production Ready (GA) 的版本了。

不過 Paul McCullagh ( 的開發者) 寫了一篇「」,裡面發現他已經把 PBXT 改到本身已經不是瓶頸,所以反過來開始看 MySQL 的問題...

裡面有很多很有趣的惡搞 (像是他覺得,如果在他的環境裡如果拿掉某些 POSIX mutex lock 不會遇到問題,他就先拔掉 lock 然後看效能可以提昇多少,如果不能拿掉,他就用自己改寫的 spinlock 或是其他方式替代),除此之外,文章裡還有一些數據可以看,可以看出他一步一步改善所走過的路,以及還有哪些地方值得改善。

最後改出來的成果相當輝煌,改到有 60% 的時間會因為在等網路另一邊的 query 進來。

在 comment 有人有提到可以用 --with-fast-mutexes,會把 POSIX mutex lock 換成 spinlock,不知道效果怎麼樣... (我發現 裡的版本沒有支援這個選項,我送了個 PR,用 Ports 的人可以更方便的設定這個選項:)

jQuery UI 的 Sortables 與 Click 事件犯衝的解法...

(我用的是 1.2.6 + jQuery UI 1.5.1) 裡有一個 ,實際用了後發現本來上面的 click 事件會失效,這點在國外也有討論到:

看起來是因為 jQuery UI Sortables 裡對 click 處理的方式會造成現有的 click event 失效,似乎沒有辦法直接從 source 部份解決,所以有人提出 workaround。

workaround 是多包一個 span,然後設定 handle 指到這個 span 上,告訴 jQuery UI Sortables 有哪些可以被拖拉,這樣 click 事件就會分開處理,於是就可以動了...

舉個例子來說,本來是:

$('.sortables').sortable({items: '.items'});

現在變成:

$('.sortables').sortable({handle: '.items > span', items: '.items'});

不是很讓人滿意的作法,但可以解決問題。

再次換到 Google Reader...

這幾天的 怪怪的,像是自己會登出 (看起來後面某台伺服器的 session 有問題),有時候會出現 500 Internal Server Error,以及偶而會出現 200 條未讀 (但 refresh 後就好了)。

趁著這次不穩定再次跳槽到 ,發現又跟印象中的不一樣了,希望這次能用的比較順手...

Firefox 的兩三事...

這幾天跟 有關的事情不少:

MySQL 的 ORDER BY RAND() 的替代方案

這篇 所提到 的「」這篇文章裡為了找到 ORDER BY RAND() 的替代方案,花了不少功夫解釋。

(PS:我跟 同屬 的一員,其中本篇文章所提到的 主機目前也放在 PIXNET 的機房裡)

最原始的想法是:

SELECT MAX(id) FROM table;
### 在 application 取一個 1 到 id 中間的值
SELECT * FROM table WHERE id = ...;

但這篇文章要探討的是如何在 裡全部做完,所以重點放在如何在 MySQL 裡取得 randid。

首先是透過 RAND() 幫忙:

SELECT RAND() * MAX(id) FROM random;

然後發現有小數點,所以用 CEIL() 變成:

SELECT CEIL(RAND() * MAX(id)) FROM random;

但這個 SQL query 效率不太好:如果有 1M rows,就會跑了 1M 次。所以利用 subquery 改寫成:

SELECT CEIL(RAND() * (SELECT MAX(id) FROM random));

EXPLAIN 檢查看起來不錯,所以包成 subquery 拉出隨機選出的 row:

SELECT name FROM random WHERE id = (SELECT CEIL(RAND() * (SELECT MAX(id) FROM random)));

結果發現速度不佳,用 EXPLAIN 檢查發現是因為 subquery optimization 被取消。所以改用其他的方法,像是利用 temporily table 與 JOIN

SELECT name FROM random JOIN (SELECT CEIL(RAND() * (SELECT MAX(id) FROM random)) AS id) AS r2 USING(id);

速度沒什麼問題,用 EXPLAIN 檢查看起來也都 ok 了,所以我們要處理 id 不連續的情況,也就是有「洞」的狀態,所以取比這個 randid 大的第一個 row:

SELECT name FROM random AS r1 JOIN (SELECT (RAND() * (SELECT MAX(id) FROM random)) AS id) AS r2 WHERE r1.id >= r2.id ORDER BY r1.id ASC LIMIT 1;

至於更後面為了要做到在 non-uniform distribution 下的 ORDER BY RAND() 效果所花的功夫太大 (像是透過 trigger 產生某個 uniform 欄位,然後就可以用那個欄位用上面的方法處理),一般人應該用不到。需要的人就麻煩自己去看了 :p