近日被要求要針對一份執行計畫作較細化的列示,之前已想辦法用Project配合Excel提供作業規劃了,要再細化?!嗯~~我想,對於主管,恐怕得用別的方式展示計畫,目標是易於在第一眼就表達相關作業的規劃緣由與關係。突然想到之前曾稍稍碰過的Mind manager tool,因為之前根本沒好好思考過它,更別提能夠體會其價值;試著下載XMind這套工具,它還有臺灣代理,相關資源與參考資料整理得似乎不錯,花了不到1hr邊使用邊畫出我的第一個心智圖,漸漸體會它對思考、釐清相關想發、思維方面有其妙的助益,看來是值得我花點心思study。
1970年代,英國人東尼‧博贊 (Tony Buzan) 為了提昇思考能力,想出了一種利用圖形來輔助思考的方法,他提出的這個輔助工具就是『心智圖』。
比起單純的使用文字,利用圖形輔助思考有時更加直覺。心智圖可以利用不同顏色的線條及各式各樣的圖案加深整體印象。也有人說,因為心智圖是一種圖像,我們要辨識心智圖時會用到平常較少使用的右腦,等於是在平常使用的左腦之外再加上右腦的輔助,所以對於記憶有莫大的幫助。
找到一些網上先進們文章、網站:
以 XMind 心智圖整理重點並匯至 Word 運用 、█大麋鹿走地圖█▇▅▂ 、克明大大的鮮思維-採購了 XMind Pro (2年三組授權) 心智圖軟件 。
2010年9月23日 星期四
2010年9月12日 星期日
可快速Note所見文章、網誌
新建了我的 tumblr http://dayder.tumblr.com/
話說~~ Blogger為何沒有這功能,配合在 IE上新加按鈕~超讚
(以下內容原文參 http://ifrs-1.blogspot.com/2010/07/tumblr.html )
Tumblr是什麼呢?嗯!是很懶的部落格專門用來隨時筆記使用的~
首先,當然是先進Tumblr,註冊,然後自定一個URL;接著,這網站會要求你先貼個什麼東西<--這個「什麼東西」就是先上傳你的大頭貼啦~
進Appearance去上傳吧!但是你當然不用呆呆的就真的上傳自己的照片,網民當久了,應該知道上傳什麼東東比較恰當吧! @@
接著,進到Goodies,看到一個叫Share on Tumblr的Icon,不用客氣,就直接用滑鼠按著那個按鈕,拖到瀏覽器上面隨便一個顯眼的地方,接著,大功告成!
到任一個blog,你只要看了喜歡,就可以在法律規定的範圍內將那段文字或圖片或影片選取後,去點剛才前面提到的,你已拖到瀏覽器上方的Share on Tumblr,然後,你還可以加個註解或感想之類的,接著,這些你選取的內容自己就會到你的Tumblr區塊了!
話說~~ Blogger為何沒有這功能,配合在 IE上新加按鈕~超讚
(以下內容原文參 http://ifrs-1.blogspot.com/2010/07/tumblr.html )
Tumblr是什麼呢?嗯!是很懶的部落格專門用來隨時筆記使用的~
首先,當然是先進Tumblr,註冊,然後自定一個URL;接著,這網站會要求你先貼個什麼東西<--這個「什麼東西」就是先上傳你的大頭貼啦~
進Appearance去上傳吧!但是你當然不用呆呆的就真的上傳自己的照片,網民當久了,應該知道上傳什麼東東比較恰當吧! @@
接著,進到Goodies,看到一個叫Share on Tumblr的Icon,不用客氣,就直接用滑鼠按著那個按鈕,拖到瀏覽器上面隨便一個顯眼的地方,接著,大功告成!
到任一個blog,你只要看了喜歡,就可以在法律規定的範圍內將那段文字或圖片或影片選取後,去點剛才前面提到的,你已拖到瀏覽器上方的Share on Tumblr,然後,你還可以加個註解或感想之類的,接著,這些你選取的內容自己就會到你的Tumblr區塊了!
2010年8月18日 星期三
PowerPoint Template
做報告都少不了PowerPoint這套簡報軟體,雖然它本身有內建一些簡報的背景範本,但樣式不多,很容易與其他同學或同事用到一樣的ppt簡報背景,找了幾個不錯的PowerPoint 背景免費下載站:
1. http://office.microsoft.com/en-us/templates/CT101172721033.aspx
2. http://www.brainybetty.com/
3. http://www.presentationhelper.co.uk/free_powerpoint_template.htm
4. http://www.presentationpoint.com/powerpoint-templates/index.htm
5. http://inzones.com/free-templates.htm
6. http://www.indezine.com/powerpoint/templates/freetemplates.html
7. http://www.presentersresource.com/
8. http://jc-schools.net/tutorials/PPT-games/
9. http://www.mastertemplates.com/powerpoint-templates.htm
10. http://www.ebibleteacher.com/backgrnd.html
11. http://www.templateswise.com/
12. http://www.freeppttemplates.com/
1. http://office.microsoft.com/en-us/templates/CT101172721033.aspx
2. http://www.brainybetty.com/
3. http://www.presentationhelper.co.uk/free_powerpoint_template.htm
4. http://www.presentationpoint.com/powerpoint-templates/index.htm
5. http://inzones.com/free-templates.htm
6. http://www.indezine.com/powerpoint/templates/freetemplates.html
7. http://www.presentersresource.com/
8. http://jc-schools.net/tutorials/PPT-games/
9. http://www.mastertemplates.com/powerpoint-templates.htm
10. http://www.ebibleteacher.com/backgrnd.html
11. http://www.templateswise.com/
12. http://www.freeppttemplates.com/
2010年7月29日 星期四
CANON 對焦系統
對焦sensor是兩兩成對 也就說兩個senser組成一個對焦單元
sensor排列方式有水平 有垂直排列
水平排列的sensor 對物體是垂直線最敏感 對物體是水平線會無法對焦
同理 垂直排列的sensor 對物體是水平線最敏感 對物體是垂直線會無法對焦
十字型就是有兩對(4個) sensor 分別是水平排列及垂直排列 所以不管物體是水平線 或垂直線都會有相對應的對焦sensor可以感應對焦 對焦成功機率相對提高
對焦精度不同於以上的概念 canon 對於對焦精度區分成兩種
一種是一般精度 另一種是高精度
一般精度 :只要主體影像落在景深內就算對焦完成
高精度:需要落在1/3 景深內才算對焦成功
所以高精準度的那一對sensor 與一般精準度的sensor不一樣 ,需要更多的光線才能發揮作用, 這需鏡頭支援, 也就是需要大光圈的鏡頭, 需要F2.8以上(含),例如 24-70mm F2.8,135mm F2.0 ,50mm F1.4 , 85mm F1.2
一般精準度sensor 對焦時對光量需求沒有那麼高 所以F5.6以上的鏡頭都可以對焦,幾乎所有原廠鏡頭都包含
如果最大光圈是 F8的鏡頭會發生什麼事 ? 有可能無法自動對焦 這種情形只好改為手動對焦 以上報告
註:對焦時鏡頭光圈都是全開的 直到按下快門時才會縮到設定的光圈
強者解說請參考
那我的20D~~~看來都是一字的吧(淚)~~
sensor排列方式有水平 有垂直排列
水平排列的sensor 對物體是垂直線最敏感 對物體是水平線會無法對焦
同理 垂直排列的sensor 對物體是水平線最敏感 對物體是垂直線會無法對焦
十字型就是有兩對(4個) sensor 分別是水平排列及垂直排列 所以不管物體是水平線 或垂直線都會有相對應的對焦sensor可以感應對焦 對焦成功機率相對提高
對焦精度不同於以上的概念 canon 對於對焦精度區分成兩種
一種是一般精度 另一種是高精度
一般精度 :只要主體影像落在景深內就算對焦完成
高精度:需要落在1/3 景深內才算對焦成功
所以高精準度的那一對sensor 與一般精準度的sensor不一樣 ,需要更多的光線才能發揮作用, 這需鏡頭支援, 也就是需要大光圈的鏡頭, 需要F2.8以上(含),例如 24-70mm F2.8,135mm F2.0 ,50mm F1.4 , 85mm F1.2
一般精準度sensor 對焦時對光量需求沒有那麼高 所以F5.6以上的鏡頭都可以對焦,幾乎所有原廠鏡頭都包含
如果最大光圈是 F8的鏡頭會發生什麼事 ? 有可能無法自動對焦 這種情形只好改為手動對焦 以上報告
註:對焦時鏡頭光圈都是全開的 直到按下快門時才會縮到設定的光圈
強者解說請參考
那我的20D~~~看來都是一字的吧(淚)~~
2010年7月16日 星期五
我在盯者你~ YN-468閃燈
自從上次被指派必須擔任婚禮攝影,而不得不面對攝影未知的領域 - 閃燈 時,
跟Allen兄商借神燈580EX,自此終於了解:好鏡可以緩緩,閃燈不能不敗的道理。
近來M01火紅的永諾YN閃燈,參考文章:
[分享]超平(便宜)燈 永諾YN-460
閃光指數直逼原廠神燈--超值外閃 永諾YN-460 II
[開箱]便宜手動閃燈 永諾YN-460 II
永諾Yongnuo YN467 PK 原廠神燈Canon 550EX
YN-468 永諾閃燈開箱
嗯~$2950連三位小朋友都不用的價錢,可以弄一之回來玩玩了。
永諾閃燈比較如下:
跟Allen兄商借神燈580EX,自此終於了解:好鏡可以緩緩,閃燈不能不敗的道理。
近來M01火紅的永諾YN閃燈,參考文章:
[分享]超平(便宜)燈 永諾YN-460
閃光指數直逼原廠神燈--超值外閃 永諾YN-460 II
[開箱]便宜手動閃燈 永諾YN-460 II
永諾Yongnuo YN467 PK 原廠神燈Canon 550EX
YN-468 永諾閃燈開箱
嗯~$2950連三位小朋友都不用的價錢,可以弄一之回來玩玩了。
永諾閃燈比較如下:
好用、取代檔案總管免費、免安裝工具:MDIE
免費好用又不用安裝~ 想不到為何不裝來用用~~~
原文請參 http://playpcesor.blogspot.com/2007/06/mdie.html
下載網址 http://www.badongo.com/file/8273387
試了一下,馬上幫我舒緩工具列爆炸的情況,
原本每每都得維持開啟 4~5個以上的檔案總管數量。
右鍵拖曳可直接上層、下層目錄,可上一頁、下一頁~~有驚豔到!
(這些M$都沒想到?)
原文請參 http://playpcesor.blogspot.com/2007/06/mdie.html
下載網址 http://www.badongo.com/file/8273387
試了一下,馬上幫我舒緩工具列爆炸的情況,
原本每每都得維持開啟 4~5個以上的檔案總管數量。
右鍵拖曳可直接上層、下層目錄,可上一頁、下一頁~~有驚豔到!
(這些M$都沒想到?)
2010年7月15日 星期四
調校SQL效能
好久沒搞SQL資料庫了,這篇文章蠻受用,為免消失,轉載於此。
(原文轉載自 http://www.wretch.cc/blog/hcu16b/10264132 )
有些程式員在撰寫前端的應用程式時,會透過各種 OOP 語言將存取資料庫的 SQL 陳述式串接起來,卻忽略了 SQL 語法的效能問題。版工曾聽過某半導體大廠的新進程式員,所兜出來的一段 PL/SQL 跑了好幾分鐘還跑不完;想當然爾,即使他前端的 AJAX 用得再漂亮,程式效能頂多也只是差強人意而已。以下是版工整理出的一些簡單心得,讓長年鑽究 ASP.NET / JSP / AJAX 等前端應用程式,卻無暇研究 SQL 語法的程式員,避免踩到一些 SQL 的效能地雷。
1、資料庫設計與規劃
‧ Primary Key 欄位的長度儘量小,能用 small integer 就不要用 integer。例如員工資料表,若能用員工編號當主鍵,就不要用身分證字號。
‧ 一般欄位亦同。若該資料表要存放的資料不會超過 3 萬筆,用 small integer 即可,不必用 integer。
‧ 文字資料欄位若長度固定,如:身分證字號,就不要用 varchar 或 nvarchar,應該用 char 或 nchar。
‧ 文字資料欄位若長度不固定,如:地址,則應該用 varchar 或 nvarchar。除了可節省儲存空間外,存取磁碟時也會較有效率。
‧ 設計欄位時,若其值可有可無,最好也給一個預設值,並設成「不允許 NULL」(一般欄位預設為「允許 NULL」)。因為 SQL Server 在存放和查詢有 NULL 的資料表時,會花費額外的運算動作 [2]。
‧ 若一個資料表的欄位過多,應垂直切割成兩個以上的資料表,並用同名的 Primary Key 一對多連結起來,如:Northwind 的 Orders、Order Details 資料表。以避免在存取資料時,以叢集索引掃描時會載入過多的資料,或修改資料時造成互相鎖定或鎖定過久。
------------------------------
2、適當地建立索引
‧ 記得自行幫 Foreign Key 欄位建立索引,即使是很少被 JOIN 的資料表亦然。
‧ 替常被查詢或排序的欄位建立索引,如:常被當作 WHERE 子句條件的欄位。
‧ 用來建立索引的欄位,長度不宜過長,不要用超過 20 個位元組的欄位,如:地址。
‧ 不要替內容重複性高的欄位建立索引,如:性別;反之,若重複性低的欄位則適合建立索引,如:姓名。
‧ 不要替使用率低的欄位建立索引。
‧ 不宜替過多欄位建立索引,否則反而會影響到新增、修改、刪除的效能,尤其是以線上交易 (OLTP) 為主的網站資料庫。
‧ 若資料表存放的資料很少,就不必刻意建立索引。否則可能資料庫沿著索引樹狀結構去搜尋索引中的資料,反而比掃描整個資料表還慢。
‧ 若查詢時符合條件的資料很多,則透過「非叢集索引」搜尋的效能,可能反而不如整個資料表逐筆掃描。
‧ 建立「叢集索引」的欄位選擇至為重要,會影響到整個索引結構的效能。要用來建立「叢集索引」的欄位,務必選擇「整數」型別 (鍵值會較小)、唯一、不可為 NULL。
------------------------------
3、適當地使用索引
‧ 有些書籍會提到,使用 LIKE、% 做模糊查詢時,即使您已替某個欄位建立索引 (如下方例子的 CustomerID),但以常數字元開頭才會使用到索引,若以萬用字元 (%) 開頭則不會使用索引,如下所示:
USE Northwind;
GO
SELECT * FROM Orders WHERE CustomerID LIKE 'D%'; --使用索引
SELECT * FROM Orders WHERE CustomerID LIKE '%D'; --不使用索引
執行完成後按 Ctrl+L,可檢閱如下圖的「執行計畫」。
圖 1 可看出「查詢最佳化程式」有使用到索引做搜尋
圖 2 在此的叢集索引掃描,並未直接使用索引,效能上幾乎只等於掃描整個資料表
但經版工反覆測試,這種語法是否會使用到索引,抑或會逐筆掃描,並非絕對的。仍要看所下的查詢關鍵字,以及欄位內儲存的資料內容而定。但對於儲存資料筆數龐大的資料表,最好還是少用 LIKE 做模糊查詢。
‧ 以下的運算子會造成「負向查詢」,常會讓「查詢最佳化程式」無法有效地使用索引,最好能用其他運算子和語法改寫 (經版工測試,並非有負向運算子,就絕對無法使用索引):
NOT 、 != 、 <> 、 !> 、 !< 、 NOT EXISTS 、 NOT IN 、 NOT LIKE
‧ 避免讓 WHERE 子句中的欄位,去做字串串接或數字運算,否則可能導致「查詢最佳化程式」無法直接使用索引,而改採叢集索引掃描 (經版工測試並非絕對)。
‧ 資料表中的資料,會依照「叢集索引」欄位的順序存放,因此當您下 BETWEEN、GROUP BY、ORDER BY 時若有包含「叢集索引」欄位,由於資料已在資料表中排序好,因此可提升查詢速度。
‧ 若使用「複合索引」,要注意索引順序上的第一個欄位,才適合當作過濾條件。
------------------------------
4、避免在 WHERE 子句中對欄位使用函數
對欄位使用函數,也等於對欄位做運算或串接的動作,一樣可能會讓「查詢最佳化程式」無法有效地使用索引。但真正對效能影響最重大的,是當您的資料表內若有 10 萬筆資料,則在查詢時就需要呼叫函數 10 萬次,這點才是真正的效能殺手。程式員應注意,在系統開發初期可能感覺不出差異,但當系統上線且資料持續累積後,這些語法細節所造成的效能問題就會逐步浮現。
SELECT * FROM Orders WHERE DATEPART(yyyy, OrderDate) = 1996 AND DATEPART(mm, OrderDate)=7
可改成
SELECT * FROM Orders WHERE OrderDate BETWEEN '19960701' AND '19960731'
SELECT * FROM Orders WHERE SUBSTRING(CustomerID, 1, 1) = 'D'
可改成
SELECT * FROM Orders WHERE CustomerID LIKE 'D%'
注意當您在下 UPDATE、DELETE 陳述式時,若有採用 WHERE 子句,也應符合上述原則。
------------------------------
5、AND 與 OR 的使用
在 AND 運算中,「只要有一個」條件有用到索引 (如下方的 CustomerID),即可大幅提升查詢速度,如下圖 3 所示:
SELECT * FROM Orders WHERE CustomerID='VINET' AND Freight=32.3800 --使用索引,會出現下圖 3 的畫面
SELECT * FROM Orders WHERE Freight=32.3800 --不使用索引,會出現上圖 2 的畫面
圖 3
但在 OR 運算中,則要「所有的」條件都有可用的索引,才能使用索引來提升查詢速度。因此 OR 運算子的使用必須特別小心。
若您將上方 AND 的範例,邏輯運算子改成 OR 的話,如下所示:
SELECT * FROM Orders WHERE CustomerID='VINET' OR Freight=32.3800
由於無法有效地使用索引,也會出現圖 2 的畫面。
在使用 OR 運算子時,只要有一個條件 (欄位) 沒有可用的索引,則其他所有的條件 (欄位) 都有索引也沒用,只能如圖 2 般,把整個資料表或整個叢集索引都掃描過,以逐筆比對是否有符合條件的資料。
據網路上文件的說法 [1],上述的 OR 運算陳述式,我們還可用 UNION 聯集適當地改善,如下:
SELECT * FROM Orders WHERE CustomerID='VINET'
UNION
SELECT * FROM Orders WHERE Freight=32.3800
此時您再按 Ctrl+L 檢閱「執行計畫」,會發現上半段的查詢會使用索引,但下半段仍用叢集索引掃描,對效能不無小補。
------------------------------
6、適當地使用子查詢
相較於「子查詢 (Subquery)」,若能用 JOIN 完成的查詢,一般會比較建議使用後者。原因除了 JOIN 的語法較容易理解外,在多數的情況下,JOIN 的效能也會比子查詢較佳;但這並非絕對,也有的情況可能剛好相反。
我們知道子查詢可分為「獨立子查詢」和「關聯子查詢」兩種,前者指子查詢的內容可單獨執行,後者則無法單獨執行,亦即外層查詢的「每一次」查詢動作都需要引用內層查詢的資料,或內層查詢的「每一次」查詢動作都需要參考外層查詢的資料。
以下我們看一個比較極端的例子 [2]。若我們希望所有查詢出來的資料,都能另外給一個自動編號,版工我在之前的文章「用 SQL Server 2005 新增的 ROW_NUMBER 函數撰寫 GridView 分頁」中有介紹過,可用 SQL Server 2005 中新增的 ROW_NUMBER 函數輕易地達成,且 ROW_NUMBER 函數還能再加上「分群 (PARTITION BY)」等功能,而且執行效能極佳。
圖 4 將 Orders 資料表的 830 筆資料都撈出來,並在右側給一組自動編號
現在我們要如上圖 4 般,將 Northwind 中 Orders 資料表的 830 筆資料都撈出來,並自動給一組編號,若用 ROW_NUMBER 函數的寫法如下所示,而且效能極佳,只要 2 ms (毫秒),亦即千分之二秒。
SET STATISTICS TIME ON
SELECT OrderID, ROW_NUMBER() OVER(ORDER BY OrderID) AS 編號
FROM dbo.Orders
但如果是在舊版的 SQL Server 2000 中,我們可能得用以下的「子查詢」寫法:
SET STATISTICS TIME ON
SELECT OrderID,
(SELECT COUNT(*) FROM dbo.Orders AS 內圈
WHERE 內圈.OrderID <= 外圈.OrderID) AS 編號
FROM dbo.Orders AS 外圈
ORDER BY 編號
但這種舊寫法,會像先前所提到的,外層查詢的「每一次」查詢動作都需要引用內層查詢的資料。以上方例子而言,外層查詢的每一筆資料,都要等內層查詢「掃描整個資料表」並作比對和計數,因此 830 筆資料每一筆都要重複掃描整個資料表 830 次,所耗用的時間也因此爆增至 170 ms。
若您用相同的寫法,去查詢 AdventureWorks 資料庫中,有 31,465 筆資料的 Sales.SalesOrderHeader 資料表,用 ROW_NUMBER 函數要 677 ms,還不到 1 秒鐘;但用子查詢的話,居然要高達 225,735 ms,將近快 4 分鐘的時間。
雖然這是較極端的範例,但由此可知子查詢的撰寫,在使用上不可不慎,尤其是「關聯子查詢」。程式員在程式開發初期、資料量還很少時感受不到此種 SQL 語法的重大陷阱;但等到系統上線幾個月或一兩年後,可能就會有反應遲緩的現象。
------------------------------
7、其他查詢技巧
‧ DISTINCT、ORDER BY 語法,會讓資料庫做額外的計算。此外聯集的使用,若沒有要剔除重複資料的需求,使用 UNION ALL 會比 UNION 更佳,因為後者會加入類似 DISTINCT 的演算法。
‧ 在 SQL Server 2005 版本中,存取資料庫物件時,最好明確指定該物件的「結構描述 (Schema)」,也就是使用兩節式名稱。否則若呼叫者的預設 Schema 不是 dbo,則 SQL Server 在執行時,會先尋找該使用者預設 Schema 所搭配的物件,找不到的話才會轉而使用預設的 dbo,會多耗費尋找的時間。例如若要執行一個叫做 dbo.mySP1 的 Stored Procedure,應使用以下的兩節式名稱:
EXEC dbo.mySP1
------------------------------
8、儘可能用 Stored Procedure 取代前端應用程式直接存取資料表
Stored Procedure 除了經過事先編譯、效能較好以外,亦可節省 SQL 陳述式傳遞的頻寬,也方便商業邏輯的重複使用。再搭配自訂函數和 View 的使用,將來若要修改資料表結構、重新切割或反正規化時亦較方便。
------------------------------
9、儘可能在資料來源層,就先過濾資料
使用 SELECT 語法時,儘量避免傳回所有的資料至前端而不設定 WHERE 等過濾條件。雖然 ASP.NET 中 SqlDataSource、ObjectDataSource 控制項的 FilterExpression 可再做篩選,GridView 控制項的 SortExpression 可再做排序,但會多消耗掉資料庫的系統資源、Web server 的記憶體和網路頻寬。最好還是在資料庫和資料來源層,就先用 SQL 條件式篩選出所要的資料。
------------------------------
結論:
本文的觀念,不管是寫 SQL statement、Stored Procedure、自訂函數或 View 皆然。本文只是挑出程式員較容易犯的 SQL 語法效能問題,以期能在短時間瀏覽過本文後,在寫 ADO.NET 程式時能修正以往隨興的 SQL 撰寫習慣。文中提到的幾點,只不過是 SQL 語法效能議題的入門篇。後續有時間的話,版工會再補充在本帖的回應留言,或另開新主題。
(原文轉載自 http://www.wretch.cc/blog/hcu16b/10264132 )
有些程式員在撰寫前端的應用程式時,會透過各種 OOP 語言將存取資料庫的 SQL 陳述式串接起來,卻忽略了 SQL 語法的效能問題。版工曾聽過某半導體大廠的新進程式員,所兜出來的一段 PL/SQL 跑了好幾分鐘還跑不完;想當然爾,即使他前端的 AJAX 用得再漂亮,程式效能頂多也只是差強人意而已。以下是版工整理出的一些簡單心得,讓長年鑽究 ASP.NET / JSP / AJAX 等前端應用程式,卻無暇研究 SQL 語法的程式員,避免踩到一些 SQL 的效能地雷。
1、資料庫設計與規劃
‧ Primary Key 欄位的長度儘量小,能用 small integer 就不要用 integer。例如員工資料表,若能用員工編號當主鍵,就不要用身分證字號。
‧ 一般欄位亦同。若該資料表要存放的資料不會超過 3 萬筆,用 small integer 即可,不必用 integer。
‧ 文字資料欄位若長度固定,如:身分證字號,就不要用 varchar 或 nvarchar,應該用 char 或 nchar。
‧ 文字資料欄位若長度不固定,如:地址,則應該用 varchar 或 nvarchar。除了可節省儲存空間外,存取磁碟時也會較有效率。
‧ 設計欄位時,若其值可有可無,最好也給一個預設值,並設成「不允許 NULL」(一般欄位預設為「允許 NULL」)。因為 SQL Server 在存放和查詢有 NULL 的資料表時,會花費額外的運算動作 [2]。
‧ 若一個資料表的欄位過多,應垂直切割成兩個以上的資料表,並用同名的 Primary Key 一對多連結起來,如:Northwind 的 Orders、Order Details 資料表。以避免在存取資料時,以叢集索引掃描時會載入過多的資料,或修改資料時造成互相鎖定或鎖定過久。
------------------------------
2、適當地建立索引
‧ 記得自行幫 Foreign Key 欄位建立索引,即使是很少被 JOIN 的資料表亦然。
‧ 替常被查詢或排序的欄位建立索引,如:常被當作 WHERE 子句條件的欄位。
‧ 用來建立索引的欄位,長度不宜過長,不要用超過 20 個位元組的欄位,如:地址。
‧ 不要替內容重複性高的欄位建立索引,如:性別;反之,若重複性低的欄位則適合建立索引,如:姓名。
‧ 不要替使用率低的欄位建立索引。
‧ 不宜替過多欄位建立索引,否則反而會影響到新增、修改、刪除的效能,尤其是以線上交易 (OLTP) 為主的網站資料庫。
‧ 若資料表存放的資料很少,就不必刻意建立索引。否則可能資料庫沿著索引樹狀結構去搜尋索引中的資料,反而比掃描整個資料表還慢。
‧ 若查詢時符合條件的資料很多,則透過「非叢集索引」搜尋的效能,可能反而不如整個資料表逐筆掃描。
‧ 建立「叢集索引」的欄位選擇至為重要,會影響到整個索引結構的效能。要用來建立「叢集索引」的欄位,務必選擇「整數」型別 (鍵值會較小)、唯一、不可為 NULL。
------------------------------
3、適當地使用索引
‧ 有些書籍會提到,使用 LIKE、% 做模糊查詢時,即使您已替某個欄位建立索引 (如下方例子的 CustomerID),但以常數字元開頭才會使用到索引,若以萬用字元 (%) 開頭則不會使用索引,如下所示:
USE Northwind;
GO
SELECT * FROM Orders WHERE CustomerID LIKE 'D%'; --使用索引
SELECT * FROM Orders WHERE CustomerID LIKE '%D'; --不使用索引
執行完成後按 Ctrl+L,可檢閱如下圖的「執行計畫」。
圖 1 可看出「查詢最佳化程式」有使用到索引做搜尋
圖 2 在此的叢集索引掃描,並未直接使用索引,效能上幾乎只等於掃描整個資料表
但經版工反覆測試,這種語法是否會使用到索引,抑或會逐筆掃描,並非絕對的。仍要看所下的查詢關鍵字,以及欄位內儲存的資料內容而定。但對於儲存資料筆數龐大的資料表,最好還是少用 LIKE 做模糊查詢。
‧ 以下的運算子會造成「負向查詢」,常會讓「查詢最佳化程式」無法有效地使用索引,最好能用其他運算子和語法改寫 (經版工測試,並非有負向運算子,就絕對無法使用索引):
NOT 、 != 、 <> 、 !> 、 !< 、 NOT EXISTS 、 NOT IN 、 NOT LIKE
‧ 避免讓 WHERE 子句中的欄位,去做字串串接或數字運算,否則可能導致「查詢最佳化程式」無法直接使用索引,而改採叢集索引掃描 (經版工測試並非絕對)。
‧ 資料表中的資料,會依照「叢集索引」欄位的順序存放,因此當您下 BETWEEN、GROUP BY、ORDER BY 時若有包含「叢集索引」欄位,由於資料已在資料表中排序好,因此可提升查詢速度。
‧ 若使用「複合索引」,要注意索引順序上的第一個欄位,才適合當作過濾條件。
------------------------------
4、避免在 WHERE 子句中對欄位使用函數
對欄位使用函數,也等於對欄位做運算或串接的動作,一樣可能會讓「查詢最佳化程式」無法有效地使用索引。但真正對效能影響最重大的,是當您的資料表內若有 10 萬筆資料,則在查詢時就需要呼叫函數 10 萬次,這點才是真正的效能殺手。程式員應注意,在系統開發初期可能感覺不出差異,但當系統上線且資料持續累積後,這些語法細節所造成的效能問題就會逐步浮現。
SELECT * FROM Orders WHERE DATEPART(yyyy, OrderDate) = 1996 AND DATEPART(mm, OrderDate)=7
可改成
SELECT * FROM Orders WHERE OrderDate BETWEEN '19960701' AND '19960731'
SELECT * FROM Orders WHERE SUBSTRING(CustomerID, 1, 1) = 'D'
可改成
SELECT * FROM Orders WHERE CustomerID LIKE 'D%'
注意當您在下 UPDATE、DELETE 陳述式時,若有採用 WHERE 子句,也應符合上述原則。
------------------------------
5、AND 與 OR 的使用
在 AND 運算中,「只要有一個」條件有用到索引 (如下方的 CustomerID),即可大幅提升查詢速度,如下圖 3 所示:
SELECT * FROM Orders WHERE CustomerID='VINET' AND Freight=32.3800 --使用索引,會出現下圖 3 的畫面
SELECT * FROM Orders WHERE Freight=32.3800 --不使用索引,會出現上圖 2 的畫面
圖 3
但在 OR 運算中,則要「所有的」條件都有可用的索引,才能使用索引來提升查詢速度。因此 OR 運算子的使用必須特別小心。
若您將上方 AND 的範例,邏輯運算子改成 OR 的話,如下所示:
SELECT * FROM Orders WHERE CustomerID='VINET' OR Freight=32.3800
由於無法有效地使用索引,也會出現圖 2 的畫面。
在使用 OR 運算子時,只要有一個條件 (欄位) 沒有可用的索引,則其他所有的條件 (欄位) 都有索引也沒用,只能如圖 2 般,把整個資料表或整個叢集索引都掃描過,以逐筆比對是否有符合條件的資料。
據網路上文件的說法 [1],上述的 OR 運算陳述式,我們還可用 UNION 聯集適當地改善,如下:
SELECT * FROM Orders WHERE CustomerID='VINET'
UNION
SELECT * FROM Orders WHERE Freight=32.3800
此時您再按 Ctrl+L 檢閱「執行計畫」,會發現上半段的查詢會使用索引,但下半段仍用叢集索引掃描,對效能不無小補。
------------------------------
6、適當地使用子查詢
相較於「子查詢 (Subquery)」,若能用 JOIN 完成的查詢,一般會比較建議使用後者。原因除了 JOIN 的語法較容易理解外,在多數的情況下,JOIN 的效能也會比子查詢較佳;但這並非絕對,也有的情況可能剛好相反。
我們知道子查詢可分為「獨立子查詢」和「關聯子查詢」兩種,前者指子查詢的內容可單獨執行,後者則無法單獨執行,亦即外層查詢的「每一次」查詢動作都需要引用內層查詢的資料,或內層查詢的「每一次」查詢動作都需要參考外層查詢的資料。
以下我們看一個比較極端的例子 [2]。若我們希望所有查詢出來的資料,都能另外給一個自動編號,版工我在之前的文章「用 SQL Server 2005 新增的 ROW_NUMBER 函數撰寫 GridView 分頁」中有介紹過,可用 SQL Server 2005 中新增的 ROW_NUMBER 函數輕易地達成,且 ROW_NUMBER 函數還能再加上「分群 (PARTITION BY)」等功能,而且執行效能極佳。
圖 4 將 Orders 資料表的 830 筆資料都撈出來,並在右側給一組自動編號
現在我們要如上圖 4 般,將 Northwind 中 Orders 資料表的 830 筆資料都撈出來,並自動給一組編號,若用 ROW_NUMBER 函數的寫法如下所示,而且效能極佳,只要 2 ms (毫秒),亦即千分之二秒。
SET STATISTICS TIME ON
SELECT OrderID, ROW_NUMBER() OVER(ORDER BY OrderID) AS 編號
FROM dbo.Orders
但如果是在舊版的 SQL Server 2000 中,我們可能得用以下的「子查詢」寫法:
SET STATISTICS TIME ON
SELECT OrderID,
(SELECT COUNT(*) FROM dbo.Orders AS 內圈
WHERE 內圈.OrderID <= 外圈.OrderID) AS 編號
FROM dbo.Orders AS 外圈
ORDER BY 編號
但這種舊寫法,會像先前所提到的,外層查詢的「每一次」查詢動作都需要引用內層查詢的資料。以上方例子而言,外層查詢的每一筆資料,都要等內層查詢「掃描整個資料表」並作比對和計數,因此 830 筆資料每一筆都要重複掃描整個資料表 830 次,所耗用的時間也因此爆增至 170 ms。
若您用相同的寫法,去查詢 AdventureWorks 資料庫中,有 31,465 筆資料的 Sales.SalesOrderHeader 資料表,用 ROW_NUMBER 函數要 677 ms,還不到 1 秒鐘;但用子查詢的話,居然要高達 225,735 ms,將近快 4 分鐘的時間。
雖然這是較極端的範例,但由此可知子查詢的撰寫,在使用上不可不慎,尤其是「關聯子查詢」。程式員在程式開發初期、資料量還很少時感受不到此種 SQL 語法的重大陷阱;但等到系統上線幾個月或一兩年後,可能就會有反應遲緩的現象。
------------------------------
7、其他查詢技巧
‧ DISTINCT、ORDER BY 語法,會讓資料庫做額外的計算。此外聯集的使用,若沒有要剔除重複資料的需求,使用 UNION ALL 會比 UNION 更佳,因為後者會加入類似 DISTINCT 的演算法。
‧ 在 SQL Server 2005 版本中,存取資料庫物件時,最好明確指定該物件的「結構描述 (Schema)」,也就是使用兩節式名稱。否則若呼叫者的預設 Schema 不是 dbo,則 SQL Server 在執行時,會先尋找該使用者預設 Schema 所搭配的物件,找不到的話才會轉而使用預設的 dbo,會多耗費尋找的時間。例如若要執行一個叫做 dbo.mySP1 的 Stored Procedure,應使用以下的兩節式名稱:
EXEC dbo.mySP1
------------------------------
8、儘可能用 Stored Procedure 取代前端應用程式直接存取資料表
Stored Procedure 除了經過事先編譯、效能較好以外,亦可節省 SQL 陳述式傳遞的頻寬,也方便商業邏輯的重複使用。再搭配自訂函數和 View 的使用,將來若要修改資料表結構、重新切割或反正規化時亦較方便。
------------------------------
9、儘可能在資料來源層,就先過濾資料
使用 SELECT 語法時,儘量避免傳回所有的資料至前端而不設定 WHERE 等過濾條件。雖然 ASP.NET 中 SqlDataSource、ObjectDataSource 控制項的 FilterExpression 可再做篩選,GridView 控制項的 SortExpression 可再做排序,但會多消耗掉資料庫的系統資源、Web server 的記憶體和網路頻寬。最好還是在資料庫和資料來源層,就先用 SQL 條件式篩選出所要的資料。
------------------------------
結論:
本文的觀念,不管是寫 SQL statement、Stored Procedure、自訂函數或 View 皆然。本文只是挑出程式員較容易犯的 SQL 語法效能問題,以期能在短時間瀏覽過本文後,在寫 ADO.NET 程式時能修正以往隨興的 SQL 撰寫習慣。文中提到的幾點,只不過是 SQL 語法效能議題的入門篇。後續有時間的話,版工會再補充在本帖的回應留言,或另開新主題。
2010年7月6日 星期二
2010年5月11日 星期二
最佳化 Visual Studio 2008 執行速度
(感謝Allen分享)
●關閉起始頁
工具 -> 選項 環境 -> 啟動,改變 啟動時 的屬性為 顯示空白環境
●關閉歡迎畫面
在 Microsoft Visual Studio 2008 的捷徑上按滑鼠右鍵,選 內容
在 目標 的最後,加上參數 /nosplash
●關閉動畫
工具 -> 選項 -> 環境,把 動畫環境工具 取消
●關閉追蹤修訂
工具 -> 選項 -> 文字編輯器 追蹤修訂 取消
●關閉 ToolboxPopulate
工具 -> 選項 -> Windows Form 設計 -> 工具箱,把 Auto ToolboxPopulate 設定為 False
將專案建置的元件自動加入工具箱的功能關閉
剛剛按照網頁上的說明,將設定一一改變,果真啟動 Visual Studio 2008 快了許多!
●關閉起始頁
工具 -> 選項 環境 -> 啟動,改變 啟動時 的屬性為 顯示空白環境
●關閉歡迎畫面
在 Microsoft Visual Studio 2008 的捷徑上按滑鼠右鍵,選 內容
在 目標 的最後,加上參數 /nosplash
●關閉動畫
工具 -> 選項 -> 環境,把 動畫環境工具 取消
●關閉追蹤修訂
工具 -> 選項 -> 文字編輯器 追蹤修訂 取消
●關閉 ToolboxPopulate
工具 -> 選項 -> Windows Form 設計 -> 工具箱,把 Auto ToolboxPopulate 設定為 False
將專案建置的元件自動加入工具箱的功能關閉
剛剛按照網頁上的說明,將設定一一改變,果真啟動 Visual Studio 2008 快了許多!
VM 參考資料
感謝Tyler 2月分享:
這裡簡單找了一些vm的資料供大家參考目前VM主機是安裝VMware Server 1.0(free)
最新版是2.0(free),且支援64bit guest os
有一種說法是Microsft Hyper-V的效能比VMWare Server好,不曉得真實性如何
而且灌Windows Server 2008是免不了的
另外市面上效能最佳的vm應該是VMware ESX,但對週邊的支援差,現在也有免費精簡版叫VMware ESXi 它比較特別的是不需安裝作業系統,因此guest os非常的原生(所謂的半虛擬化),所以效能會很好
VMWare Server 2.0
https://www.vmware.com/products/server/overview.html
Microsoft Hyper-V Server
http://www.microsoft.com/hyper-v-server/en/us/default.aspx
VMware ESXi導入
http://applepig.idv.tw/archives/919
效能比較(2007年的資料)
http://blog.nonestyle.net/2007/03/vmware-virtual-pc-parallels-virtualbox.html
VMware ESX/ESXi/Server效能比較
http://www.vixual.net/blog/archives/543
虛擬機之家
http://www.xuniji.com/
2010年3月1日 星期一
錄音好物 - OLYMPUS WS-500M
幾年前MP3正夯時,曾因需要錄音並能當MP3隨身聽買了1G的產品,但錄音效果實在差強人意,而且一年前它也早壽終正寢。
近日因為上課需要錄音,上網survey了一下錄音筆,竟發現有人談到~見 懇請大大推薦錄音筆 一文,另外,[開箱] OLYMPUS WS-500M 也值得一讀,搭配下載韌體更新,可直接錄製MP3。 沒想到這好物只能從美國代購取得,從沒天頂的拍賣場花了 $3050大洋還直奔五股自取(還迷路繞到泰山去了...);
今天上課錄製的心得是~好得不得了啊,上了9小時的課,用掉1顆AAA (4號)電池,還不錯哩,音樂MP3聽起來的效果也很讚,有SRS也可以設BASS,按鍵配置蠻順手的,不用看書明書也能馬上上手,還有SLOW、FAST語言學習功能,都是很實用的功能,唯一可以挑剔的,應該就是美感的問題了,塑膠味頗重,果然是美國老粗的style(跟SONY日本美型派的真差得遠),但對我而言,無損對它的讚賞。
近日因為上課需要錄音,上網survey了一下錄音筆,竟發現有人談到~見 懇請大大推薦錄音筆 一文,另外,[開箱] OLYMPUS WS-500M 也值得一讀,搭配下載韌體更新,可直接錄製MP3。 沒想到這好物只能從美國代購取得,從沒天頂的拍賣場花了 $3050大洋還直奔五股自取(還迷路繞到泰山去了...);
今天上課錄製的心得是~好得不得了啊,上了9小時的課,用掉1顆AAA (4號)電池,還不錯哩,音樂MP3聽起來的效果也很讚,有SRS也可以設BASS,按鍵配置蠻順手的,不用看書明書也能馬上上手,還有SLOW、FAST語言學習功能,都是很實用的功能,唯一可以挑剔的,應該就是美感的問題了,塑膠味頗重,果然是美國老粗的style(跟SONY日本美型派的真差得遠),但對我而言,無損對它的讚賞。
2010年1月11日 星期一
訂閱:
文章 (Atom)