tag:blogger.com,1999:blog-59465307047421309702024-03-06T16:20:07.273+08:00Jax 的工作紀錄除了在整理學習上的經驗,同時也能幫助其他需要的人Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.comBlogger3125tag:blogger.com,1999:blog-5946530704742130970.post-8444822696862903002020-07-31T20:01:00.002+08:002020-07-31T23:08:58.175+08:00資料庫設計原則以前跟同事一起訂下的資料庫設計原則,來減少一開始設計不好造成事後要進行大改的風險。<br />
<br />
實體關聯的設計是最需要謹慎的,這裡一旦與規格差太多,程式可能就要重寫。<br />
<br />
欄位名稱建議在系統中是唯一的,這樣可以減少 JOIN 時還需要換名稱,FK 使用跟 PK 一樣的名稱也可以增加維護性。<br />
<br />
<br />
<hr /><br />
<h3>資料庫設計流程</h3><br />
(Instance 層級)<br />
<ul><li>依照 Instance 建立 ER 圖,須清楚描述關聯與實體</li>
<li>審視並釐清實體對於規格的含蓋範圍</li>
</ul><br />
(Table 層級)<br />
<ul><li>依照釐清後的含蓋範圍,修正 ER 圖</li>
<li>審視並確認完整 ER圖</li>
</ul><br />
(Column 層級)<br />
<ul><li>定義各資料表欄位,建立 OrgTableSchema.sql</li>
<li>審視並確認完整 Schema</li>
<li>有問題重複上述步驟</li>
</ul><br />
(Develop 層級)<br />
<ul><li>維護 OrgTableSchema.sql</li>
<li>使用 DbSchemaTool 工具產生 Schema.sql</li>
<li>建立資料庫</li>
<li>修正 Dbml</li>
<li>更新 DB 專案</li>
</ul><br />
<br />
<h3>資料表與欄位定義</h3><ul><li>Id 是 identity 去尾的縮寫,所以 d 要小寫</li>
<li>No 改成 Num 會比較好,因為會跟 Yes, No 混淆</li>
<li>Id 是流水號,其他的建議用 Num 或 Code 表示</li>
<li>避免用單單字做欄位名,盡量用多單字 ( Ex. IssueType, CompanyCode, SettingId, CompanyName )</li>
<li>盡量用 流水號 或 Guid 這類無意義的 id 做 PK</li>
<li>除了多對多的中間表,PK 都必須是單一欄位</li>
<li>資料來源為 OptionSetting, 值為 OptionId 者,欄位名稱命名須加尾贅詞 Id,型態為 INT</li>
<li>資料來源為 Enum, 欄位型態則為 Nvarchar(N)</li>
<li>盡量避免資料來源為 bool 對應 bit,因為擴充性太低,資料來源改用 Enum 對應 Nvarchar(N)</li>
<li>歷史檔與主檔的差異</li>
<ul><li>主檔的 ModifiedBy ModifierdDate 為歷史檔的 CreatedBy CreatedDate,歷史檔無 ModifiedBy ModifierdDate</li>
<li>新增歷史檔的 PK , 主檔的 PK 設定為 FK</li>
<li>其餘欄位應該與主檔相同</li>
</ul><li>每一個 FK 需預設建立 IX,其餘調整於開發完成後,依照使用者回報進行調整</li>
<li>多對多的中間表如果超過 3 個附加欄位,必須用一般的方式設計</li>
</ul><br />
<br />
<h3>PK 必須使用 Guid 的情況</h3><ul><li>如果只保留短期資料,但會有大量新增或刪除(每天一萬筆新增)</li>
<li>如果有多系統都可以新增資料,最後要合流的狀況</li>
</ul><br />
<br />
<h3>設計 Table 的欄位順序</h3><ol><li>PK</li>
<li>FK [主檔]</li>
<li>FK [選項]</li>
<li>AK</li>
<li>其餘不重要的資料欄位</li>
<li>CreatedBy</li>
<li>CreatedDate</li>
<li>ModifiedBy</li>
<li>ModifierdDate</li>
</ol><br />
<br />
<h3>資料型態</h3><ul><li>文字 : NVARCHAR 長度為預定輸入的兩倍</li>
<li>日期 : DATETIMEOFFSET 具有時區紀錄(MSDN 建議)</li>
<li>時間 : TIME</li>
<li>整數 : INT</li>
<li>Enum : NVARCHAR (32)</li>
<li>Guid : UNIQUEIDENTIFIER</li>
<li>金錢 : MONEY</li>
<li>精確浮點數 : DECIMAL (18, 4)</li>
</ul><br />
<br />
<h3>鍵值規則</h3><ul><li>Table 規則 {ProjectName}_{TableName}<br />
Ex: WMS_Carrier</li>
<li>Foreign Key 規則 FK_{ProjectName}_{TableName}_{Columns}<br />
Ex: FK_WMS_CarrierMaterial_CarrierId</li>
<li>Unique 規則 AK_{ProjectName}_{TableName}_{Columns}<br />
Ex: FK_WMS_CarrierMaterial_CarrierId</li>
<li>Index 規則 IX_{ProjectName}_{TableName}_{Columns}<br />
Ex: IX_WMS_CarrierMaterial_CarrierId</li>
</ul><br />
<br />
<h3>縮寫解釋</h3><ul><li>PK: Primary Key</li>
<li>FK: Foreign Key</li>
<li>AK: Alternate Key</li>
<li>IX: IndeX</li>
<li>CK: ChecK</li>
<li>DF: DeFault</li>
</ul><br />
<br />
<h3>MSSQL 定序設定</h3><br />
定序 Chinese_Taiwan_Stroke_CS_AI<br />
<br />
_CS 區分大小寫<br />
_CI 不區分大小寫<br />
<br />
_AS 區分腔調 a != á<br />
_AI 不區分腔調<br />
<br />
_KS 區分日文假名字元<br />
_WS 區分全形與半形字元<br />
<br />
定序會影響查詢與唯一值的判定,例如不區分大小的定序在 WHERE 'abc' = 'ABC' 會是 true。<br />
<br />
定序選擇並沒有標準答案,我個人是採用區分大小的定序,如果規格是不區分的時候,再用程式轉大寫或小寫,這部分可以在 DAO 統一完成,雖然也會有遺漏的情況,但至少是可以由程式掌控,如果出現只有某些不區分,而大部分還是區分的時候,還是由程式掌控會比較好。<br />
<br />
<br />
<br />
Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-55480413068311281562017-09-01T11:27:00.000+08:002017-09-01T11:29:22.939+08:00SQL Server Management Studio 資料表設計模式顯示欄位描述 <br />
開啟登錄檔編輯器 regedit.exe <br />
搜尋 SSVPropViewColumnsSQL70 及 SSVPropViewColumnsSQL80 <br />
將值從 1,2,6; 改為 1,2,6,17;<br />
<br />
各個屬性欄位代號:<br />
<pre>1: Column Name
2: Data Type
3: Length
4: Precision
5: Scale
6: Allow Nulls
7: Default Value
8: Identity
9: Identity Seed
10: Identity Increment
11: Row GUID
12: Nullable
13: Condensed Type
14: Not for Replication
15: Formula
16: Collation
17: Description
</pre><br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicoX6JfbJq4x4cZWbkQRd7rZ-nr7C8VOqy9n8g-pdaSbHNejWwl1A4D4xTLJLRGayl5vaq0HhwZpO698-6sn4dh7YnK_rp0e2csOuZcCrQ-qMlxJjhPqWTWWjO86tpkCzJr1e7Ns1nc213/s1600/MWSnap124.png"><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicoX6JfbJq4x4cZWbkQRd7rZ-nr7C8VOqy9n8g-pdaSbHNejWwl1A4D4xTLJLRGayl5vaq0HhwZpO698-6sn4dh7YnK_rp0e2csOuZcCrQ-qMlxJjhPqWTWWjO86tpkCzJr1e7Ns1nc213/s550/MWSnap124.png" /></a><br />
<br />
<a href="https://4.bp.blogspot.com/-o5BU68BCQ18/WajTPWv4ttI/AAAAAAAAN8I/ffwgywSoVsYUIfydV0sTFuhQd4XYY3VuACLcBGAs/s1600/MWSnap125.png"><img src="https://4.bp.blogspot.com/-o5BU68BCQ18/WajTPWv4ttI/AAAAAAAAN8I/ffwgywSoVsYUIfydV0sTFuhQd4XYY3VuACLcBGAs/s550/MWSnap125.png" /></a>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-23030989327272617592013-08-25T13:56:00.000+08:002014-10-08T13:29:31.867+08:00[轉載] 調校 SQL 以徹底改善應用程式效能轉載自:<a target="_blank" href="http://blog.xuite.net/j2ee/code/15120677">調校 SQL 以徹底改善應用程式效能</a><br />
<br />
有些程式員在撰寫前端的應用程式時,會透過各種 OOP 語言將存取資料庫的 SQL 陳述式串接起來,卻忽略了 SQL 語法的效能問題。版工曾聽過某半導體大廠的新進程式員,所兜出來的一段 PL/SQL 跑了好幾分鐘還跑不完;想當然爾,即使他前端的 AJAX 用得再漂亮,程式效能頂多也只是差強人意而已。以下是版工整理出的一些簡單心得,讓長年鑽究 ASP.NET / JSP / AJAX 等前端應用程式,卻無暇研究 SQL 語法的程式員,避免踩到一些 SQL 的效能地雷。<br />
<br />
<br />
<strong>1、資料庫設計與規劃</strong><br />
<ul><li>Primary Key 欄位的長度儘量小,能用 small integer 就不要用 integer。例如員工資料表,若能用員工編號當主鍵,就不要用身分證字號。</li>
<li>一般欄位亦同。若該資料表要存放的資料不會超過 3 萬筆,用 small integer 即可,不必用 integer。</li>
<li>文字資料欄位若長度固定,如:身分證字號,就不要用 varchar 或 nvarchar,應該用 char 或 nchar。</li>
<li>文字資料欄位若長度不固定,如:地址,則應該用 varchar 或 nvarchar。除了可節省儲存空間外,存取磁碟時也會較有效率。</li>
<li>設計欄位時,若其值可有可無,最好也給一個預設值,並設成「不允許 NULL」(一般欄位預設為「允許 NULL」)。因為 SQL Server 在存放和查詢有 NULL 的資料表時,會花費額外的運算動作 [2]。</li>
<li>若一個資料表的欄位過多,應垂直切割成兩個以上的資料表,並用同名的 Primary Key 一對多連結起來,如:Northwind 的 Orders、Order Details 資料表。以避免在存取資料時,以叢集索引掃描時會載入過多的資料,或修改資料時造成互相鎖定或鎖定過久。</li>
</ul><br />
<br />
<hr /><strong>2、適當地建立索引</strong><br />
<ul><li>記得自行幫 Foreign Key 欄位建立索引,即使是很少被 JOIN 的資料表亦然。</li>
<li>替常被查詢或排序的欄位建立索引,如:常被當作 WHERE 子句條件的欄位。</li>
<li>用來建立索引的欄位,長度不宜過長,不要用超過 20 個位元組的欄位,如:地址。</li>
<li>不要替內容重複性高的欄位建立索引,如:性別;反之,若重複性低的欄位則適合建立索引,如:姓名。</li>
<li>不要替使用率低的欄位建立索引。</li>
<li>不宜替過多欄位建立索引,否則反而會影響到新增、修改、刪除的效能,尤其是以線上交易 (OLTP) 為主的網站資料庫。</li>
<li>若資料表存放的資料很少,就不必刻意建立索引。否則可能資料庫沿著索引樹狀結構去搜尋索引中的資料,反而比掃描整個資料表還慢。</li>
<li>若查詢時符合條件的資料很多,則透過「非叢集索引」搜尋的效能,可能反而不如整個資料表逐筆掃描。</li>
<li>建立「叢集索引」的欄位選擇至為重要,會影響到整個索引結構的效能。要用來建立「叢集索引」的欄位,務必選擇「整數」型別 (鍵值會較小)、唯一、不可為 NULL。</li>
</ul><br />
<br />
<hr /><strong>3、適當地使用索引</strong><br />
<ul><li>有些書籍會提到,使用 LIKE、% 做模糊查詢時,即使您已替某個欄位建立索引 (如下方例子的 CustomerID),但以常數字元開頭才會使用到索引,若以萬用字元 (%) 開頭則不會使用索引,如下所示:<br />
<pre class="sql:nogutter:nocontrols" name="code">USE Northwind;
GO
SELECT * FROM Orders WHERE CustomerID LIKE 'D%'; --使用索引
SELECT * FROM Orders WHERE CustomerID LIKE '%D'; --不使用索引
</pre><br />
執行完成後按 Ctrl+L,可檢閱如下圖的「執行計畫」。<br />
<br />
<img src="https://lh3.googleusercontent.com/-KBw56MgqA20/UhmXa87iZmI/AAAAAAAANHg/8VzDH18EwyM/s512/mssql-optimization-1.jpg" style="border:none;" /><br />
圖 1 可看出「查詢最佳化程式」有使用到索引做搜尋<br />
<br />
<img src="https://lh3.googleusercontent.com/-VfW8IGvmdn0/UhmXa8a2ClI/AAAAAAAANHg/X2XWjCDM5DA/s512/mssql-optimization-2.jpg" style="border:none;" /><br />
圖 2 在此的叢集索引掃描,並未直接使用索引,效能上幾乎只等於掃描整個資料表<br />
<br />
但經版工反覆測試,這種語法是否會使用到索引,抑或會逐筆掃描,並非絕對的。仍要看所下的查詢關鍵字,以及欄位內儲存的資料內容而定。但對於儲存資料筆數龐大的資料表,最好還是少用 LIKE 做模糊查詢。<br />
<br />
</li>
<li>以下的運算子會造成「負向查詢」,常會讓「查詢最佳化程式」無法有效地使用索引,最好能用其他運算子和語法改寫 (經版工測試,並非有負向運算子,就絕對無法使用索引):<br />
<code>NOT 、 != 、 <> 、 !> 、 !< 、 NOT EXISTS 、 NOT IN 、 NOT LIKE</code></li>
<li>避免讓 WHERE 子句中的欄位,去做字串串接或數字運算,否則可能導致「查詢最佳化程式」無法直接使用索引,而改採叢集索引掃描 (經版工測試並非絕對)。</li>
<li>資料表中的資料,會依照「叢集索引」欄位的順序存放,因此當您下 BETWEEN、GROUP BY、ORDER BY 時若有包含「叢集索引」欄位,由於資料已在資料表中排序好,因此可提升查詢速度。</li>
<li>若使用「複合索引」,要注意索引順序上的第一個欄位,才適合當作過濾條件。</li>
</ul><br />
<br />
<hr /><strong>4、避免在 WHERE 子句中對欄位使用函數</strong><br />
<br />
對欄位使用函數,也等於對欄位做運算或串接的動作,一樣可能會讓「查詢最佳化程式」無法有效地使用索引。但真正對效能影響最重大的,是當您的資料表內若有 10 萬筆資料,則在查詢時就需要呼叫函數 10 萬次,這點才是真正的效能殺手。程式員應注意,在系統開發初期可能感覺不出差異,但當系統上線且資料持續累積後,這些語法細節所造成的效能問題就會逐步浮現。<br />
<br />
<pre class="sql:nogutter:nocontrols" name="code">SELECT * FROM Orders WHERE DATEPART(yyyy, OrderDate) = 1996 AND DATEPART(mm, OrderDate)=7
-- 可改成
SELECT * FROM Orders WHERE OrderDate BETWEEN '19960701' AND '19960731'
</pre><br />
<pre class="sql:nogutter:nocontrols" name="code">SELECT * FROM Orders WHERE SUBSTRING(CustomerID, 1, 1) = 'D'
-- 可改成
SELECT * FROM Orders WHERE CustomerID LIKE 'D%'
</pre><br />
注意當您在下 UPDATE、DELETE 陳述式時,若有採用 WHERE 子句,也應符合上述原則。<br />
<br />
<br />
<hr /><strong>5、AND 與 OR 的使用</strong><br />
<br />
在 AND 運算中,「只要有一個」條件有用到索引 (如下方的 CustomerID),即可大幅提升查詢速度,如下圖 3 所示:<br />
<br />
<pre class="sql:nogutter:nocontrols" name="code">SELECT * FROM Orders WHERE CustomerID='VINET' AND Freight=32.3800
--使用索引,會出現下圖 3 的畫面
</pre><br />
<pre class="sql:nogutter:nocontrols" name="code">SELECT * FROM Orders WHERE Freight=32.3800
--不使用索引,會出現上圖 2 的畫面
</pre><br />
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigWdMoBqfL-DZyFX9iHyM6ExH9ciZB8u86JuWTJJSLnoJ7auH2UUgh93GyPxpwrJrMb8-M_0Fswvw-UUbLv2TB2fCEqpZB-b_uQ51Xu3Clafxj4YY4OUVus9TPilPhdX6LDqsgCfVx7JE8/s512/mssql-optimization-3.jpg" style="border:none;" /><br />
圖 3<br />
<br />
但在 OR 運算中,則要「所有的」條件都有可用的索引,才能使用索引來提升查詢速度。因此 OR 運算子的使用必須特別小心。<br />
<br />
若您將上方 AND 的範例,邏輯運算子改成 OR 的話,如下所示:<br />
<br />
<pre class="sql:nogutter:nocontrols" name="code">SELECT * FROM Orders WHERE CustomerID='VINET' OR Freight=32.3800
</pre><br />
由於無法有效地使用索引,也會出現圖 2 的畫面。<br />
<br />
在使用 OR 運算子時,只要有一個條件 (欄位) 沒有可用的索引,則其他所有的條件 (欄位) 都有索引也沒用,只能如圖 2 般,把整個資料表或整個叢集索引都掃描過,以逐筆比對是否有符合條件的資料。<br />
<br />
<br />
據網路上文件的說法 [1],上述的 OR 運算陳述式,我們還可用 UNION 聯集適當地改善,如下:<br />
<br />
<pre class="sql:nogutter:nocontrols" name="code">SELECT * FROM Orders WHERE CustomerID='VINET'
UNION
SELECT * FROM Orders WHERE Freight=32.3800
</pre><br />
此時您再按 Ctrl+L 檢閱「執行計畫」,會發現上半段的查詢會使用索引,但下半段仍用叢集索引掃描,對效能不無小補。<br />
<br />
<br />
<hr /><strong>6、適當地使用子查詢</strong><br />
<br />
相較於「子查詢 (Subquery)」,若能用 JOIN 完成的查詢,一般會比較建議使用後者。原因除了 JOIN 的語法較容易理解外,在多數的情況下,JOIN 的效能也會比子查詢較佳;但這並非絕對,也有的情況可能剛好相反。<br />
<br />
我們知道子查詢可分為「獨立子查詢」和「關聯子查詢」兩種,前者指子查詢的內容可單獨執行,後者則無法單獨執行,亦即外層查詢的「每一次」查詢動作都需要引用內層查詢的資料,或內層查詢的「每一次」查詢動作都需要參考外層查詢的資料。<br />
<br />
以下我們看一個比較極端的例子 [2]。若我們希望所有查詢出來的資料,都能另外給一個自動編號,版工我在之前的文章「用 SQL Server 2005 新增的 ROW_NUMBER 函數撰寫 GridView 分頁」中有介紹過,可用 SQL Server 2005 中新增的 ROW_NUMBER 函數輕易地達成,且 ROW_NUMBER 函數還能再加上「分群 (PARTITION BY)」等功能,而且執行效能極佳。<br />
<br />
<img src="https://lh6.googleusercontent.com/-kuVFN51A_XQ/UhmXbQA3D5I/AAAAAAAANHg/TSuJR5s2sMA/s512/mssql-optimization-4.jpg" style="border:none;" /><br />
圖 4 將 Orders 資料表的 830 筆資料都撈出來,並在右側給一組自動編號<br />
<br />
現在我們要如上圖 4 般,將 Northwind 中 Orders 資料表的 830 筆資料都撈出來,並自動給一組編號,若用 ROW_NUMBER 函數的寫法如下所示,而且效能極佳,只要 2 ms (毫秒),亦即千分之二秒。<br />
<br />
<pre class="sql:nogutter:nocontrols" name="code">SET STATISTICS TIME ON
SELECT OrderID, ROW_NUMBER() OVER(ORDER BY OrderID) AS 編號
FROM dbo.Orders
</pre><br />
但如果是在舊版的 SQL Server 2000 中,我們可能得用以下的「子查詢」寫法:<br />
<br />
<pre class="sql:nogutter:nocontrols" name="code">SET STATISTICS TIME ON
SELECT OrderID,
(SELECT COUNT(*) FROM dbo.Orders AS 內圈
WHERE 內圈.OrderID <= 外圈.OrderID) AS 編號
FROM dbo.Orders AS 外圈
ORDER BY 編號
</pre><br />
但這種舊寫法,會像先前所提到的,外層查詢的「每一次」查詢動作都需要引用內層查詢的資料。以上方例子而言,外層查詢的每一筆資料,都要等內層查詢「掃描整個資料表」並作比對和計數,因此 830 筆資料每一筆都要重複掃描整個資料表 830 次,所耗用的時間也因此爆增至 170 ms。<br />
<br />
若您用相同的寫法,去查詢 AdventureWorks 資料庫中,有 31,465 筆資料的 Sales.SalesOrderHeader 資料表,用 ROW_NUMBER 函數要 677 ms,還不到 1 秒鐘;但用子查詢的話,居然要高達 225,735 ms,將近快 4 分鐘的時間。<br />
<br />
雖然這是較極端的範例,但由此可知子查詢的撰寫,在使用上不可不慎,尤其是「關聯子查詢」。程式員在程式開發初期、資料量還很少時感受不到此種 SQL 語法的重大陷阱;但等到系統上線幾個月或一兩年後,可能就會有反應遲緩的現象。<br />
<br />
<br />
<hr /><strong>7、其他查詢技巧</strong><br />
<ul><li>DISTINCT、ORDER BY 語法,會讓資料庫做額外的計算。此外聯集的使用,若沒有要剔除重複資料的需求,使用 UNION ALL 會比 UNION 更佳,因為後者會加入類似 DISTINCT 的演算法。</li>
<li>在 SQL Server 2005 版本中,存取資料庫物件時,最好明確指定該物件的「結構描述 (Schema)」,也就是使用兩節式名稱。否則若呼叫者的預設 Schema 不是 dbo,則 SQL Server 在執行時,會先尋找該使用者預設 Schema 所搭配的物件,找不到的話才會轉而使用預設的 dbo,會多耗費尋找的時間。例如若要執行一個叫做 dbo.mySP1 的 Stored Procedure,應使用以下的兩節式名稱:<br />
<pre class="sql:nogutter:nocontrols" name="code">EXEC dbo.mySP1
</pre></li>
</ul><br />
<br />
<hr /><strong>8、儘可能用 Stored Procedure 取代前端應用程式直接存取資料表</strong><br />
<br />
Stored Procedure 除了經過事先編譯、效能較好以外,亦可節省 SQL 陳述式傳遞的頻寬,也方便商業邏輯的重複使用。再搭配自訂函數和 View 的使用,將來若要修改資料表結構、重新切割或反正規化時亦較方便。<br />
<br />
<br />
<hr /><strong>9、儘可能在資料來源層,就先過濾資料</strong><br />
<br />
使用 SELECT 語法時,儘量避免傳回所有的資料至前端而不設定 WHERE 等過濾條件。雖然 ASP.NET 中 SqlDataSource、ObjectDataSource 控制項的 FilterExpression 可再做篩選,GridView 控制項的 SortExpression 可再做排序,但會多消耗掉資料庫的系統資源、Web server 的記憶體和網路頻寬。最好還是在資料庫和資料來源層,就先用 SQL 條件式篩選出所要的資料。<br />
<br />
<br />
<hr /><strong>結論:</strong><br />
<br />
本文的觀念,不管是寫 SQL statement、Stored Procedure、自訂函數或 View 皆然。本文只是挑出程式員較容易犯的 SQL 語法效能問題,以期能在短時間瀏覽過本文後,在寫 ADO.NET 程式時能修正以往隨興的 SQL 撰寫習慣。文中提到的幾點,只不過是 SQL 語法效能議題的入門篇。後續有時間的話,版工會再補充在本帖的回應留言,或另開新主題。<br />
<br />
<br />
<hr /><strong>參考文件:</strong><br />
<br />
[1] SQL查詢最佳化 (網際烏托邦):<br />
<a target="_blank" href="http://www.ithome.com.tw/plog/index.php?op=ViewArticle&articleId=5421&blogId=620">http://www.ithome.com.tw/plog/index.php?op=ViewArticle&articleId=5421&blogId=620</a><br />
<br />
<strong>參考書籍:</strong><br />
<br />
[2] SQL Server 2005 Performance Tuning 效能調校:<br />
作者:胡百敬、姚巧枚、劉承修<br />
出版社:悅知出版社<br />
<a target="_blank" href="http://tlsj.tenlong.com.tw/WebModule/BookSearch/bookSearchViewAction.do?isbn=9789866761225&sid=41966">http://tlsj.tenlong.com.tw/WebModule/BookSearch/bookSearchViewAction.do?isbn=9789866761225&sid=41966</a><br />
<br />
[3] SQL Server 2005 完全實戰:<br />
作者:章立民<br />
出版社:碁峰出版社<br />
<br />
<strong>相關文件:</strong><br />
<br />
[4] 臺大醫院資料庫分割疏失,系統幾近停擺 (ITHome):<br />
<a target="_blank" href="http://www.ithome.com.tw/itadm/article.php?c=43597">http://www.ithome.com.tw/itadm/article.php?c=43597</a><br />
<br />
[5] 當DataGrid遇見100萬筆資料:<br />
<a target="_blank" href="http://blog.sina.com.tw/4907/article.php?pbgid=4907&entryid=3921">http://blog.sina.com.tw/4907/article.php?pbgid=4907&entryid=3921</a><br />
<br />
[6] ASP.NET 2.0 GridView 範例集 - 「4-8-4、GridView的效能」:<br />
<a target="_blank" href="http://blog.csdn.net/Code6421/archive/2007/12/22/1958167.aspx">http://blog.csdn.net/Code6421/archive/2007/12/22/1958167.aspx</a><br />
<br />
[7] 有關開啟頁面時,一次載入數千筆資料的效能問題:<br />
<a target="_blank" href="http://www.blueshop.com.tw:80/board/show.asp?subcde=BRD200709141021458MV">http://www.blueshop.com.tw:80/board/show.asp?subcde=BRD200709141021458MV</a><br />
<br />
Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0