2010年5月12日 星期三

DB實作心得---SQL JOIN語法

因為都是用Hibernate,所以好久沒碰這種語法了...老實說以前在學SQL的時候,也一直沒很認真的搞懂。一直到最近為了案子,才又比較認真的去看了...
找了幾篇網友分享的文章,都講得很清楚,所以就不在贅述:
一般來說,我們通常都會儘量用一個SQL statement的方式來完成所需要的查詢。而其中都儘量可以用JOIN的方式來把所需要的資料串出來。不過我也有看到有網友發表心得,表示在MySQL上,進行較複雜的JOIN時,效率會很糟糕,甚至會造成DB table被lock過久的情況。事實上,幾年前我自己也用過MySQL,也是發現它在作較複雜JOIN時,效率真的不好...所以後來我就都改用PostgreSQL。

而在Hibernate中,我所常用的Criteria是一種物件式的查詢方式,它建立跟其他table JOIN的方式是透過createCriteria()或是createAlias()。透過這兩種method,可以把要查詢的root entity跟child entity作JOIN。在建立這種JOIN關係時,Hibernate預設是使用inner join的方式,所以在某些情況會無法正確的找到所要資料,甚至會出現LazyInitializationException。此時,可以試試看在這兩種method的呼叫時,加上Criteria.LEFT_JOIN,這樣Hibernate會以Left outer join的方式處理,也許就可以成功的找到所要的資料了。

我個人認為與其使用一個很複雜的SQL statement來增加查詢效率,未必比使用多個簡單的SQL statement來取出資料再透過自己程式邏輯作處理來的容易跟快速...

Database系統實做心得---SQL調校

做了很久跟DB有關的開發工作,但是其實後來大部分都是靠Hibernate為主。透過它,開發者不再需要傷神有關DB底層的設定與SQL語法的管理與維護。不過也變得比較偷懶,比較不會去在意SQL語法上的調校。
在網路上有許多高手有此道的獨到心得,我只也是從中獲得一點點,這兩偏是個人覺得還蠻不錯的:Database Index 筆記調校 SQL 以徹底改善應用程式效能

其中有些跟DB table schema設計或是SQL語法的技巧,不過在Hibernate中,要使用這些技巧可能就不是那麼容易。Hibernate是允許使用者自行設定這些東西產生的方法,甚至可以自訂SQL statement。不過個人覺得Hibernate自己所產生的schema跟SQL statement已經很不錯了,除非真的很有特殊的需求,不然實在也沒必要自己搞(如果都要自己搞,那就失去用Hibernate的意義了)。

不過兩篇文章都有提到的一個重點:index。在Hibernate中,也有支援產生index的機制,但是只會對primary key跟unique column自動產生。雖然在Hibernate Annotation Extensions中有@index的annotation可以指定對某個property產生db index,但是這功能只有在透過Hibernate作第一次DB schema建立時有效;若是指定的index的table已經存在的話,這機制不會有作用,就必須手動產生。根據上面兩篇文章的內容,產生與刪除index的SQL DML為:
create index index_mytable_mycol on mytable(mycol)
drop index index_mytable_mycol

而根據上述兩篇文章的講法,幾乎都認為應該對FK也設定index比較好。當然有些但書,例如在主table資料量有到一定量以上的時候才會比較有效果等等的。