Tìm hiểu Execution Plan trong Sql Server 2008 (Phần 1)
`wp_posts` (`ID`, `post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_title`, `post_excerpt`, `post_status`, `comment_status`, `ping_status`, `post_password`, `post_name`, `to_ping`, `pinged`, `post_modified`, `post_modified_gmt`, `post_content_filtered`, `post_parent`, `guid`, `menu_order`, `post_type`, `post_mime_type`, `comment_count`) VALUES
(274, 1, '2011-04-17 14:45:39', '2011-04-17 14:45:39', '<span style="color: #0000ff;"><strong>ĐÔI NÉT VỀ EXECUTION PLAN</strong></span>\r\n<ul>\r\n <li>Thời gian ban đầu làm việc với Sql Server 2008, tôi chẳng quan tâm Execution Plan là gì, chẳng màng đọc các thông số, chẳng biết vai trò của Execution Plan đối với hệ thống Sql Server.</li>\r\n <li>Qua quá trình tìm hiểu để tăng tốc hiệu năng cho Sql Server (Sql Performance Tuning), tôi đã nhận ra vai trò cực kỳ quan trọng của Execution Plan trong việc tối ưu hệ thống Sql. Xin cho vài ví dụ:\r\n<ul>\r\n <li style="text-align: justify;"><span style="color: #008000;"><strong>Thời gian thực thi câu truy vấn</strong></span>=<strong><span style="color: #008000;">thời gian tạo Execution Plan + thời gian thực thi câu </span></strong><span style="color: #008000;"><strong>truy vấn</strong></span><strong><span style="color: #008000;"> dựa trên Execution Plan đó</span></strong>. Do đó, giảm chi phí tạo Execution Plan rất quan trọng, góp phần giảm tải công việc cho Sql Server.</li>\r\n <li><strong><span style="color: #008000;">Dựa vào Execution Plan ta có thể biết một câu truy vấn có dùng Index hay không, và hiệu quả của Index đó.</span></strong></li>\r\n <li style="text-align: justify;"><span style="color: #000000;">Để tạo ra Execution Plan cần tốn chu trình CPU để tìm ra Execution được cho là <span style="color: #008000;"><strong>''tốt’ </strong></span>và không gian bộ nhớ (Ram) để lưu trữ Execution Plan đó để dùng lại lần sau</span>. Có 1 thành phần quan trọng trong Sql Server là <strong><span style="color: #008000;">Query Optimizer,</span></strong> nhiệm vụ của <span style="color: #008000;"><strong>Query Optimizer</strong></span> là tìm ra Execution Plan được cho là là <span style="color: #008000;"><strong>‘tốt’</strong></span>, chứ không phải <span style="color: #008000;"><strong>‘tốt nhất’</strong></span>, vì có thể cùng một câu truy vấn, nhưng có hàng chục, hàng trăm Execution Plan khác nhau có thể được tạo ra để phục vụ câu truy vấn đó.</li>\r\n</ul>\r\n</li>\r\n</ul>\r\n<ul>\r\n <li>Tôi đã thực hiện bài thực hành trên Database của tôi, viết 1 câu truy vấn và cho chạy 5 lần với 5 tham số khác nhau.\r\n<ul>\r\n <li>Lúc chưa có nhiều kiến thức về Execution Plan thì tôi nghĩ rằng sau khi chạy câu truy vấn lần 1, Sql tạo ra Execution Plan và lưu trong bộ nhớ, 4 lần sau Sql sẽ dùng lại Execution Plan đó.</li>\r\n <li style="text-align: justify;">Nhưng tôi đã lầm, nếu tôi viết không cẩn thận, cả 5 lần thực thi câu truy vấn, Sql Server sẽ tạo ra đến 5 Execution Plan và lưu vào bộ nhớ. Như vậy, tôi đã bắt CPU phải làm việc đến 5 lần để tạo ra 5 Execution Plan có nội dung giống nhau, tốn bộ nhớ gấp 5 lần để lưu Execution Plan đó. Trong khi nếu tôi viết đúng cách, chỉ cần 1 Execution Plan cho 5 lần thực thi câu truy vấn, và chỉ tốn bộ nhớ để lưu 1 Execution Plan. Ở đây chỉ là 5, còn hệ thống Sql Server lớn với hàng trăm, hàng ngàn câu truy vấn được thực thi liên tục thì lượng hao phí là quá lớn không thể chấp nhận được.</li>\r\n</ul>\r\n</li>\r\n</ul>\r\n<table border="1" cellspacing="0" cellpadding="0" width="601" height="101">\r\n<tbody>\r\n<tr>\r\n<td width="197" valign="top"></td>\r\n<td width="197" valign="top"><span style="color: #008000;"><strong>Viết đúng cách</strong></span></td>\r\n<td width="197" valign="top"><span style="color: #008000;"><strong>Viết không đúng cách</strong></span></td>\r\n</tr>\r\n<tr>\r\n<td width="197" valign="top"><strong>Số lần thực thi câu truy vấn</strong></td>\r\n<td style="text-align: center;" width="197" valign="top">5</td>\r\n<td style="text-align: center;" width="197" valign="top">5</td>\r\n</tr>\r\n<tr>\r\n<td width="197" valign="top"><strong>Số Execution Plan tạo ra</strong></td>\r\n<td style="text-align: center;" width="197" valign="top">1</td>\r\n<td style="text-align: center;" width="197" valign="top">5</td>\r\n</tr>\r\n<tr>\r\n<td width="197" valign="top"><strong>Số lần bắt CPU làm việc để tạo ra Execution Plan</strong></td>\r\n<td style="text-align: center;" width="197" valign="top">1</td>\r\n<td style="text-align: center;" width="197" valign="top">5</td>\r\n</tr>\r\n<tr>\r\n<td width="197" valign="top"><strong>Số Execution Plan được lưu trong bộ nhớ</strong></td>\r\n<td style="text-align: center;" width="197" valign="top">1</td>\r\n<td style="text-align: center;" width="197" valign="top">5</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n<p style="text-align: left;"><!--[if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:PunctuationKerning /> <w:ValidateAgainstSchemas /> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:Compatibility> <w:BreakWrappedTables /> <w:SnapToGridInCell /> <w:WrapTextWithPunct /> <w:UseAsianBreakRules /> <w:DontGrowAutofit /> </w:Compatibility> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> </w:WordDocument> </xml><![endif]--><!--[if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" LatentStyleCount="156"> </w:LatentStyles> </xml><![endif]--><!--[if gte mso 10]>\r\n<mce:style><! /* Style Definitions */ table.MsoNormalTable {mso-style-name:"Table Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0in 5.4pt 0in 5.4pt; mso-para-margin:0in; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;} --></p>\r\n<!--[endif]-->\r\n<p class="MsoNormal"><span style="color: #0000ff;"><strong>EXECUTION PLAN ĐƯỢC TẠO RA TỪ ĐÂU?</strong></span></p>\r\n<p class="MsoNormal" style="text-align: justify;">Có một thành phần quan trọng trong Sql Server là <strong><span style="color: green;">Query Optimizer,</span></strong> nhiệm vụ của <strong><span style="color: green;">Query Optimizer</span></strong> là tìm ra Execution Plan được cho là là <strong><span style="color: green;">‘tốt’</span></strong>, chứ không phải <strong><span style="color: green;">‘tốt nhất’</span></strong>, vì có thể cùng một câu truy vấn, nhưng có hàng chục, hàng trăm Execution Plan khác nhau có thể được tạo ra để phục vụ câu truy vấn đó.</p>\r\n<p class="MsoNormal"><span style="color: #0000ff;"><strong>EXECUTION PLAN ĐƯỢC LƯU Ở ĐÂU?</strong></span></p>\r\n<p class="MsoNormal">Execution Plan được lưu trong <span style="color: #008000;"><strong>Plan Cache </strong></span>hay còn gọi là <strong><span style="color: #008000;">Procedure Cache</span></strong>.</p>\r\n<p class="MsoNormal">Procedure Cache và một phần trong <span style="color: #008000;"><strong>Sql Server Buffer Cache</strong></span>.</p>\r\n<p class="MsoNormal">Việc lưu Plan trong bộ nhớ cho phép Sql Server tránh phải lập lại toàn bộ quy trình tối ưu câu truy vấn khi nhiều câu truy vấn giống nhau được submit.</p>\r\n<p class="MsoNormal"><!--[if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:PunctuationKerning /> <w:ValidateAgainstSchemas /> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:Compatibility> <w:BreakWrappedTables /> <w:SnapToGridInCell /> <w:WrapTextWithPunct /> <w:UseAsianBreakRules /> <w:DontGrowAutofit /> </w:Compatibility> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> </w:WordDocument> </xml><![endif]--><!--[if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" LatentStyleCount="156"> </w:LatentStyles> </xml><![endif]--><!--[if gte mso 10]>\r\n<mce:style><! /* Style Definitions */ table.MsoNormalTable {mso-style-name:"Table Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0in 5.4pt 0in 5.4pt; mso-para-margin:0in; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;} --></p>\r\n<!--[endif]-->\r\n<p class="MsoNormal"><span style="color: #0000ff;"><strong>EXECUTION PLAN ĐƯỢC LƯU NHƯ THẾ NÀO?</strong></span></p>\r\n<p class="MsoNormal" style="text-align: justify;">Khi một Execution Plan mới được lưu vào Procedure Cache, tất nhiên kích cỡ của Procedure Cache sẽ phát triển, hay nói cách khác, lượng bộ nhớ để lưu trữ Execution Plan sẽ tăng lên. Bộ nhớ có giới hạn, không thể lưu hết tất cả Execution Plan được tạo ra, Sql Server sẽ tự động điều chỉnh số lượng Execution Plan trong Procedure Cache bằng cách giữ lại những Execution Plan thường được sử dụng, loại bỏ những Execution Plan không được sử dụng sau một khỏang thời gian nhất định.</p>\r\n<p class="MsoNormal" style="text-align: justify;">Vậy Sql Server nhận biết các Execution Plan thường được sử dụng như thế nào? Câu trả lời là Sql Server sẽ gán tuổi cho các Execution Plan được tạo ra, tuổi của Execution Plan chính là chi phí để tạo ra Execution Plan đó. Một câu truy vấn phức tạp sẽ có tuổi cao hơn một câu truy vấn đơn giản, vì chi phí tạo ra Execution Plan của câu truy vấn phức tạp cao hơn câu truy vấn đơn giản.</p>\r\n<p class="MsoNormal" style="text-align: justify;">Sau một khỏang thời gian xác định, tuổi của các Execution Plan sẽ bị giảm bởi tiến trình Lazy Writer. Tiến trình Lazy Writer chịu trách nhiệm quản lý các tiến trình chạy ngầm trong SQL Server.</p>\r\n<p class="MsoNormal" style="text-align: justify;">Nếu một Execution Plan không được sử dụng trong một thời gian dài, tuổi của nó sẽ giảm xuống còn 0. Chi phí tạo ra Execution Plan càng rẻ, tuổi của nó sẻ càng nhanh chóng giảm xuống còn 0, và sẽ bị loại bỏ khỏi bộ nhớ nếu SQL Server cần bộ nhớ cho những việc khác. Tuy nhiên, nếu hệ thống còn dư bộ nhớ, những Execution Plan có tuổi là 0 vẫn sẽ được giữ lại một thời gian dài để sử dụng lại nếu cần.</p>\r\n<p class="MsoNormal" style="text-align: justify;">Mỗi khi Execution Plan được tái sử dụng, tuổi của nó sẽ tăng lên bằng cách cộng thêm chi phí tạo ra Execution Plan đó. Ví dụ tôi có một Execution Plan được tạo ra với chi phí là 100, nó sẽ có tuổi là 100. Khi Execution Plan này được tái sử dụng, tuổi của nó sẽ tăng lên là 200. Nếu không được tái sử dụng thường xuyên, tuổi của Execution Plan sẽ bị giảm dần bởi tiến trình Lazy Writer như đã nói ở trên.</p>\r\n<p style="text-align: right;">Quang Vinh\r\nmai.quangvinh@sqlvn.com</p>\r\n\r\n<div id="_mcePaste" class="mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow: hidden;"><!--[if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:PunctuationKerning /> <w:ValidateAgainstSchemas /> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:Compatibility> <w:BreakWrappedTables /> <w:SnapToGridInCell /> <w:WrapTextWithPunct /> <w:UseAsianBreakRules /> <w:DontGrowAutofit /> </w:Compatibility> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> </w:WordDocument> </xml><![endif]--><!--[if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" LatentStyleCount="156"> </w:LatentStyles> </xml><![endif]--><!--[if gte mso 10]> <mce:style><! /* Style Definitions */ table.MsoNormalTable {mso-style-name:"Table Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0in 5.4pt 0in 5.4pt; mso-para-margin:0in; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;} --> <!--[endif]--><strong><span style="color: blue;">ĐÔI NÉT VỀ EXECUTION PLAN</span></strong> \r\n<ul type="disc">\r\n <li class="MsoNormal">Thời gian ban đầu làm việc với Sql Server 2008, tôi chẳng quan tâm Execution Plan là gì, chẳng màng đọc các thông số, chẳng biết vai trò của Execution Plan đối với hệ thống Sql Server.</li>\r\n <li class="MsoNormal">Qua quá trình tìm hiểu để tăng tốc hiệu năng cho Sql Server (Sql Performance Tuning), tôi đã nhận ra vai trò cực kỳ quan trọng của Execution Plan trong việc tối ưu hệ thống Sql, cho nên tôi viết lọat bài về Execution Plan để chia sẽ kiến thức với mọi người. Xin cho vài ví dụ:\r\n<ul type="circle">\r\n <li class="MsoNormal"><strong><span style="color: green;">Thời gian thực thi câu query</span></strong>=<strong><span style="color: green;">thời gian tạo Execution Plan + thời gian thực thi câu query dựa trên Execution Plan đó</span></strong>. Do đó, giảm chi phí tạo Execution Plan rất quan trọng, góp phần giảm tải công việc cho Sql Server.</li>\r\n <li class="MsoNormal"><strong><span style="color: green;">Dựa vào Execution Plan ta có thể biết một câu truy vấn có dùng Index hay không, và hiệu quả của Index đó.</span></strong></li>\r\n <li class="MsoNormal"><span style="color: black;">Để tạo ra Execution Plan cần tốn chu trình CPU để tìm ra Execution Plan được cho là </span><strong><span style="color: green;">''tốt’ </span></strong><span style="color: black;">và không gian bộ nhớ (Ram) để lưu trữ Execution Plan đó để dùng lại lần sau</span>.</li>\r\n</ul>\r\n</li>\r\n</ul>\r\n<ul type="disc">\r\n <li class="MsoNormal">Tôi đã thực hiện bài thực hành trên Database của tôi, viết 1 câu truy vấn và cho chạy 5 lần với 5 tham số khác nhau.\r\n<ul type="circle">\r\n <li class="MsoNormal">Lúc chưa có nhiều kiến thức về Execution Plan thì tôi nghĩ rằng sau khi chạy câu truy vấn lần 1, Sql tạo ra Execution Plan và lưu trong bộ nhớ, 4 lần sau Sql sẽ dùng lại Execution Plan đó.</li>\r\n <li class="MsoNormal">Nhưng tôi đã lầm, nếu tôi viết không cẩn thận, cả 5 lần thực thi câu truy vấn, Sql Server sẽ tạo ra đến 5 Execution Plan và lưu vào bộ nhớ. Như vậy, tôi đã bắt CPU phải làm việc đến 5 lần để tạo ra 5 Execution Plan có nội dung giống nhau, tốn bộ nhớ gấp 5 lần để lưu Execution Plan đó. Trong khi nếu tôi viết đúng cách, chỉ cần 1 Execution Plan cho 5 lần thực thi câu truy vấn, và chỉ tốn bộ nhớ để lưu 1 Execution Plan. Ở đây chỉ là 5, còn hệ thống Sql Server lớn với hàng trăm, hàng ngàn câu truy vấn được thực thi liên tục thì lượng hao phí là quá lớn không thể chấp nhận được.</li>\r\n</ul>\r\n</li>\r\n</ul>\r\n<table class="MsoNormalTable" border="1" cellspacing="0" cellpadding="0">\r\n<tbody>\r\n<tr>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal"> </p>\r\n</td>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal"><strong><span style="color: green;">Viết đúng cách</span></strong></p>\r\n</td>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal"><strong><span style="color: green;">Viết không đúng cách</span></strong></p>\r\n</td>\r\n</tr>\r\n<tr>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal"><strong>Số lần thực thi câu truy vấn</strong></p>\r\n</td>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal" style="text-align: center;">5</p>\r\n</td>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal" style="text-align: center;">5</p>\r\n</td>\r\n</tr>\r\n<tr>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal"><strong>Số Execution Plan tạo ra</strong></p>\r\n</td>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal" style="text-align: center;">1</p>\r\n</td>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal" style="text-align: center;">5</p>\r\n</td>\r\n</tr>\r\n<tr>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal"><strong>Số lần bắt CPU làm việc để tạo ra Execution Plan</strong></p>\r\n</td>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal" style="text-align: center;">1</p>\r\n</td>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal" style="text-align: center;">5</p>\r\n</td>\r\n</tr>\r\n<tr>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal"><strong>Số Execution Plan được lưu trong bộ nhớ</strong></p>\r\n</td>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal" style="text-align: center;">1</p>\r\n</td>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal" style="text-align: center;">5</p>\r\n</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n<p class="MsoNormal"><strong>EXECUTION PLAN ĐƯỢC TẠO RA TỪ ĐÂU?</strong></p>\r\n<p class="MsoNormal">Có 1 thành phần quan trọng trong Sql Server là <strong><span style="color: green;">Query Optimizer,</span></strong> nhiệm vụ của <strong><span style="color: green;">Query Optimizer</span></strong> là tìm ra Execution Plan được cho là là <strong><span style="color: green;">‘tốt’</span></strong>, chứ không phải <strong><span style="color: green;">‘tốt nhất’</span></strong>, vì có thể cùng một câu truy vấn, nhưng có hàng chục, hàng trăm Execution Plan khác nhau có thể được tạo ra để phục vụ câu truy vấn đó.</p>\r\n<p class="MsoNormal"><strong>EXECUTION PLAN ĐƯỢC LƯU Ở ĐÂU?</strong></p>\r\n<p class="MsoNormal">Execution Plan được lưu trong Plan Cache hay còn gọi là Procedure Cache.</p>\r\n<p class="MsoNormal">Procedure Cache và một phần trong Sql Server Buffer Cache.</p>\r\n<p class="MsoNormal">Việc lưu Plan trong bộ nhớ cho phép Sql Server tránh phải lập lại toàn bộ quy trình tối ưu câu truy vấn khi nhiều câu truy vấn giống nhau được submit.</p>\r\n<p style="text-align: right;">Quang Vinh\r\nmai.quangvinh@sqlvn.com</p>\r\n \r\n<p class="MsoNormal"> </p>\r\n\r\n</div>', 'Tìm hiểu Execution Plan trong Sql Server 2008 (Phần 1)', '', 'inherit', 'open', 'open', '', '266-revision-6', '', '', '2011-04-17 14:45:39', '2011-04-17 14:45:39', '', 266, 'http://sqlvn.com/uncategorized/266-revision-6.html', 0, 'revision', '', 0),
(275, 1, '2011-04-17 14:49:53', '2011-04-17 14:49:53', '<span style="color: #0000ff;"><strong>ĐÔI NÉT VỀ EXECUTION PLAN</strong></span>\r\n<ul>\r\n <li>Thời gian ban đầu làm việc với Sql Server 2008, tôi chẳng quan tâm Execution Plan là gì, chẳng màng đọc các thông số, chẳng biết vai trò của Execution Plan đối với hệ thống Sql Server.</li>\r\n <li>Qua quá trình tìm hiểu để tăng tốc hiệu năng cho Sql Server (Sql Performance Tuning), tôi đã nhận ra vai trò cực kỳ quan trọng của Execution Plan trong việc tối ưu hệ thống Sql. Xin cho vài ví dụ:\r\n<ul>\r\n <li style="text-align: justify;"><span style="color: #008000;"><strong>Thời gian thực thi câu truy vấn</strong></span>=<strong><span style="color: #008000;">thời gian tạo Execution Plan + thời gian thực thi câu </span></strong><span style="color: #008000;"><strong>truy vấn</strong></span><strong><span style="color: #008000;"> dựa trên Execution Plan đó</span></strong>. Do đó, giảm chi phí tạo Execution Plan rất quan trọng, góp phần giảm tải công việc cho Sql Server.</li>\r\n <li><strong><span style="color: #008000;">Dựa vào Execution Plan ta có thể biết một câu truy vấn có dùng Index hay không, và hiệu quả của Index đó.</span></strong></li>\r\n <li style="text-align: justify;"><span style="color: #000000;">Để tạo ra Execution Plan cần tốn chu trình CPU để tìm ra Execution được cho là <span style="color: #008000;"><strong>''tốt’ </strong></span>và không gian bộ nhớ (Ram) để lưu trữ Execution Plan đó để dùng lại lần sau</span>. Có 1 thành phần quan trọng trong Sql Server là <strong><span style="color: #008000;">Query Optimizer,</span></strong> nhiệm vụ của <span style="color: #008000;"><strong>Query Optimizer</strong></span> là tìm ra Execution Plan được cho là là <span style="color: #008000;"><strong>‘tốt’</strong></span>, chứ không phải <span style="color: #008000;"><strong>‘tốt nhất’</strong></span>, vì có thể cùng một câu truy vấn, nhưng có hàng chục, hàng trăm Execution Plan khác nhau có thể được tạo ra để phục vụ câu truy vấn đó.</li>\r\n</ul>\r\n</li>\r\n</ul>\r\n<ul>\r\n <li>Tôi đã thực hiện bài thực hành trên Database của tôi, viết 1 câu truy vấn và cho chạy 5 lần với 5 tham số khác nhau.\r\n<ul>\r\n <li>Lúc chưa có nhiều kiến thức về Execution Plan thì tôi nghĩ rằng sau khi chạy câu truy vấn lần 1, Sql tạo ra Execution Plan và lưu trong bộ nhớ, 4 lần sau Sql sẽ dùng lại Execution Plan đó.</li>\r\n <li style="text-align: justify;">Nhưng tôi đã lầm, nếu tôi viết không cẩn thận, cả 5 lần thực thi câu truy vấn, Sql Server sẽ tạo ra đến 5 Execution Plan và lưu vào bộ nhớ. Như vậy, tôi đã bắt CPU phải làm việc đến 5 lần để tạo ra 5 Execution Plan có nội dung giống nhau, tốn bộ nhớ gấp 5 lần để lưu Execution Plan đó. Trong khi nếu tôi viết đúng cách, chỉ cần 1 Execution Plan cho 5 lần thực thi câu truy vấn, và chỉ tốn bộ nhớ để lưu 1 Execution Plan. Ở đây chỉ là 5, còn hệ thống Sql Server lớn với hàng trăm, hàng ngàn câu truy vấn được thực thi liên tục thì lượng hao phí là quá lớn không thể chấp nhận được.</li>\r\n</ul>\r\n</li>\r\n</ul>\r\n<table border="1" cellspacing="0" cellpadding="0" width="601" height="101">\r\n<tbody>\r\n<tr>\r\n<td width="197" valign="top"></td>\r\n<td width="197" valign="top"><span style="color: #008000;"><strong>Viết đúng cách</strong></span></td>\r\n<td width="197" valign="top"><span style="color: #008000;"><strong>Viết không đúng cách</strong></span></td>\r\n</tr>\r\n<tr>\r\n<td width="197" valign="top"><strong>Số lần thực thi câu truy vấn</strong></td>\r\n<td style="text-align: center;" width="197" valign="top">5</td>\r\n<td style="text-align: center;" width="197" valign="top">5</td>\r\n</tr>\r\n<tr>\r\n<td width="197" valign="top"><strong>Số Execution Plan tạo ra</strong></td>\r\n<td style="text-align: center;" width="197" valign="top">1</td>\r\n<td style="text-align: center;" width="197" valign="top">5</td>\r\n</tr>\r\n<tr>\r\n<td width="197" valign="top"><strong>Số lần bắt CPU làm việc để tạo ra Execution Plan</strong></td>\r\n<td style="text-align: center;" width="197" valign="top">1</td>\r\n<td style="text-align: center;" width="197" valign="top">5</td>\r\n</tr>\r\n<tr>\r\n<td width="197" valign="top"><strong>Số Execution Plan được lưu trong bộ nhớ</strong></td>\r\n<td style="text-align: center;" width="197" valign="top">1</td>\r\n<td style="text-align: center;" width="197" valign="top">5</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n<p style="text-align: left;"><!--[if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:PunctuationKerning /> <w:ValidateAgainstSchemas /> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:Compatibility> <w:BreakWrappedTables /> <w:SnapToGridInCell /> <w:WrapTextWithPunct /> <w:UseAsianBreakRules /> <w:DontGrowAutofit /> </w:Compatibility> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> </w:WordDocument> </xml><![endif]--><!--[if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" LatentStyleCount="156"> </w:LatentStyles> </xml><![endif]--><!--[if gte mso 10]>\r\n<mce:style><! /* Style Definitions */ table.MsoNormalTable {mso-style-name:"Table Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0in 5.4pt 0in 5.4pt; mso-para-margin:0in; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;} --></p>\r\n<!--[endif]-->\r\n<p class="MsoNormal"><span style="color: #0000ff;"><strong>EXECUTION PLAN ĐƯỢC TẠO RA TỪ ĐÂU?</strong></span></p>\r\n<p class="MsoNormal" style="text-align: justify;">Có một thành phần quan trọng trong Sql Server là <strong><span style="color: green;">Query Optimizer,</span></strong> nhiệm vụ của <strong><span style="color: green;">Query Optimizer</span></strong> là tìm ra Execution Plan được cho là là <strong><span style="color: green;">‘tốt’</span></strong>, chứ không phải <strong><span style="color: green;">‘tốt nhất’</span></strong>, vì có thể cùng một câu truy vấn, nhưng có hàng chục, hàng trăm Execution Plan khác nhau có thể được tạo ra để phục vụ câu truy vấn đó.</p>\r\n<p class="MsoNormal"><span style="color: #0000ff;"><strong>EXECUTION PLAN ĐƯỢC LƯU Ở ĐÂU?</strong></span></p>\r\n<p class="MsoNormal">Execution Plan được lưu trong <span style="color: #008000;"><strong>Plan Cache </strong></span>hay còn gọi là <strong><span style="color: #008000;">Procedure Cache</span></strong>.</p>\r\n<p class="MsoNormal">Procedure Cache và một phần trong <span style="color: #008000;"><strong>Sql Server Buffer Cache</strong></span>.</p>\r\n<p class="MsoNormal">Việc lưu Plan trong bộ nhớ cho phép Sql Server tránh phải lập lại toàn bộ quy trình tối ưu câu truy vấn khi nhiều câu truy vấn giống nhau được submit.</p>\r\n<p class="MsoNormal"><!--[if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:PunctuationKerning /> <w:ValidateAgainstSchemas /> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:Compatibility> <w:BreakWrappedTables /> <w:SnapToGridInCell /> <w:WrapTextWithPunct /> <w:UseAsianBreakRules /> <w:DontGrowAutofit /> </w:Compatibility> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> </w:WordDocument> </xml><![endif]--><!--[if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" LatentStyleCount="156"> </w:LatentStyles> </xml><![endif]--><!--[if gte mso 10]>\r\n<mce:style><! /* Style Definitions */ table.MsoNormalTable {mso-style-name:"Table Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0in 5.4pt 0in 5.4pt; mso-para-margin:0in; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;} --></p>\r\n<!--[endif]-->\r\n<p class="MsoNormal"><span style="color: #0000ff;"><strong>EXECUTION PLAN ĐƯỢC LƯU NHƯ THẾ NÀO?</strong></span></p>\r\n<p class="MsoNormal" style="text-align: justify;">Khi một Execution Plan mới được lưu vào Procedure Cache, tất nhiên kích cỡ của Procedure Cache sẽ phát triển, hay nói cách khác, lượng bộ nhớ để lưu trữ Execution Plan sẽ tăng lên. Bộ nhớ có giới hạn, không thể lưu hết tất cả Execution Plan được tạo ra, Sql Server sẽ tự động điều chỉnh số lượng Execution Plan trong Procedure Cache bằng cách giữ lại những Execution Plan thường được sử dụng, loại bỏ những Execution Plan không được sử dụng sau một khỏang thời gian nhất định.</p>\r\n<p class="MsoNormal" style="text-align: justify;">Vậy Sql Server nhận biết các Execution Plan thường được sử dụng như thế nào? Câu trả lời là <strong><span style="color: #008000;">Sql Server sẽ gán tuổi cho các Execution Plan được tạo ra</span></strong>, tuổi của Execution Plan chính là chi phí để tạo ra Execution Plan đó. Một câu truy vấn phức tạp sẽ có tuổi cao hơn một câu truy vấn đơn giản, vì chi phí tạo ra Execution Plan của câu truy vấn phức tạp cao hơn câu truy vấn đơn giản.</p>\r\n<p class="MsoNormal" style="text-align: justify;">Sau một khỏang thời gian xác định, tuổi của các Execution Plan sẽ bị giảm bởi tiến trình <strong><span style="color: #008000;">Lazy Writer</span></strong>. Tiến trình Lazy Writer chịu trách nhiệm quản lý các tiến trình chạy ngầm trong SQL Server.</p>\r\n<p class="MsoNormal" style="text-align: justify;"><span style="color: #008000;"><strong>Nếu một Execution Plan không được sử dụng trong một thời gian dài, tuổi của nó sẽ giảm xuống còn 0.</strong></span> Chi phí tạo ra Execution Plan càng rẻ, tuổi của nó sẻ càng nhanh chóng giảm xuống còn 0, và sẽ bị loại bỏ khỏi bộ nhớ nếu SQL Server cần bộ nhớ cho những việc khác. Tuy nhiên, nếu hệ thống còn dư bộ nhớ, những Execution Plan có tuổi là 0 vẫn sẽ được giữ lại một thời gian dài để sử dụng lại nếu cần.</p>\r\n<p class="MsoNormal" style="text-align: justify;"><strong><span style="color: #008000;">Mỗi khi Execution Plan được tái sử dụng, tuổi của nó sẽ tăng lên bằng cách cộng thêm chi phí tạo ra Execution Plan đó.</span></strong> Ví dụ tôi có một Execution Plan được tạo ra với chi phí là 100, nó sẽ có tuổi là 100. Khi Execution Plan này được tái sử dụng, tuổi của nó sẽ tăng lên là 200. Nếu không được tái sử dụng thường xuyên, tuổi của Execution Plan sẽ bị giảm dần bởi tiến trình Lazy Writer như đã nói ở trên.</p>\r\n<p style="text-align: right;">Quang Vinh\r\nmai.quangvinh@sqlvn.com</p>\r\n\r\n<div id="_mcePaste" class="mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow: hidden;"><!--[if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:PunctuationKerning /> <w:ValidateAgainstSchemas /> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:Compatibility> <w:BreakWrappedTables /> <w:SnapToGridInCell /> <w:WrapTextWithPunct /> <w:UseAsianBreakRules /> <w:DontGrowAutofit /> </w:Compatibility> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> </w:WordDocument> </xml><![endif]--><!--[if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" LatentStyleCount="156"> </w:LatentStyles> </xml><![endif]--><!--[if gte mso 10]> <mce:style><! /* Style Definitions */ table.MsoNormalTable {mso-style-name:"Table Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0in 5.4pt 0in 5.4pt; mso-para-margin:0in; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;} --> <!--[endif]--><strong><span style="color: blue;">ĐÔI NÉT VỀ EXECUTION PLAN</span></strong> \r\n<ul type="disc">\r\n <li class="MsoNormal">Thời gian ban đầu làm việc với Sql Server 2008, tôi chẳng quan tâm Execution Plan là gì, chẳng màng đọc các thông số, chẳng biết vai trò của Execution Plan đối với hệ thống Sql Server.</li>\r\n <li class="MsoNormal">Qua quá trình tìm hiểu để tăng tốc hiệu năng cho Sql Server (Sql Performance Tuning), tôi đã nhận ra vai trò cực kỳ quan trọng của Execution Plan trong việc tối ưu hệ thống Sql, cho nên tôi viết lọat bài về Execution Plan để chia sẽ kiến thức với mọi người. Xin cho vài ví dụ:\r\n<ul type="circle">\r\n <li class="MsoNormal"><strong><span style="color: green;">Thời gian thực thi câu query</span></strong>=<strong><span style="color: green;">thời gian tạo Execution Plan + thời gian thực thi câu query dựa trên Execution Plan đó</span></strong>. Do đó, giảm chi phí tạo Execution Plan rất quan trọng, góp phần giảm tải công việc cho Sql Server.</li>\r\n <li class="MsoNormal"><strong><span style="color: green;">Dựa vào Execution Plan ta có thể biết một câu truy vấn có dùng Index hay không, và hiệu quả của Index đó.</span></strong></li>\r\n <li class="MsoNormal"><span style="color: black;">Để tạo ra Execution Plan cần tốn chu trình CPU để tìm ra Execution Plan được cho là </span><strong><span style="color: green;">''tốt’ </span></strong><span style="color: black;">và không gian bộ nhớ (Ram) để lưu trữ Execution Plan đó để dùng lại lần sau</span>.</li>\r\n</ul>\r\n</li>\r\n</ul>\r\n<ul type="disc">\r\n <li class="MsoNormal">Tôi đã thực hiện bài thực hành trên Database của tôi, viết 1 câu truy vấn và cho chạy 5 lần với 5 tham số khác nhau.\r\n<ul type="circle">\r\n <li class="MsoNormal">Lúc chưa có nhiều kiến thức về Execution Plan thì tôi nghĩ rằng sau khi chạy câu truy vấn lần 1, Sql tạo ra Execution Plan và lưu trong bộ nhớ, 4 lần sau Sql sẽ dùng lại Execution Plan đó.</li>\r\n <li class="MsoNormal">Nhưng tôi đã lầm, nếu tôi viết không cẩn thận, cả 5 lần thực thi câu truy vấn, Sql Server sẽ tạo ra đến 5 Execution Plan và lưu vào bộ nhớ. Như vậy, tôi đã bắt CPU phải làm việc đến 5 lần để tạo ra 5 Execution Plan có nội dung giống nhau, tốn bộ nhớ gấp 5 lần để lưu Execution Plan đó. Trong khi nếu tôi viết đúng cách, chỉ cần 1 Execution Plan cho 5 lần thực thi câu truy vấn, và chỉ tốn bộ nhớ để lưu 1 Execution Plan. Ở đây chỉ là 5, còn hệ thống Sql Server lớn với hàng trăm, hàng ngàn câu truy vấn được thực thi liên tục thì lượng hao phí là quá lớn không thể chấp nhận được.</li>\r\n</ul>\r\n</li>\r\n</ul>\r\n<table class="MsoNormalTable" border="1" cellspacing="0" cellpadding="0">\r\n<tbody>\r\n<tr>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal"> </p>\r\n</td>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal"><strong><span style="color: green;">Viết đúng cách</span></strong></p>\r\n</td>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal"><strong><span style="color: green;">Viết không đúng cách</span></strong></p>\r\n</td>\r\n</tr>\r\n<tr>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal"><strong>Số lần thực thi câu truy vấn</strong></p>\r\n</td>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal" style="text-align: center;">5</p>\r\n</td>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal" style="text-align: center;">5</p>\r\n</td>\r\n</tr>\r\n<tr>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal"><strong>Số Execution Plan tạo ra</strong></p>\r\n</td>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal" style="text-align: center;">1</p>\r\n</td>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal" style="text-align: center;">5</p>\r\n</td>\r\n</tr>\r\n<tr>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal"><strong>Số lần bắt CPU làm việc để tạo ra Execution Plan</strong></p>\r\n</td>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal" style="text-align: center;">1</p>\r\n</td>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal" style="text-align: center;">5</p>\r\n</td>\r\n</tr>\r\n<tr>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal"><strong>Số Execution Plan được lưu trong bộ nhớ</strong></p>\r\n</td>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal" style="text-align: center;">1</p>\r\n</td>\r\n<td style="width: 147.75pt; padding: 0in;" width="197" valign="top">\r\n<p class="MsoNormal" style="text-align: center;">5</p>\r\n</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n<p class="MsoNormal"><strong>EXECUTION PLAN ĐƯỢC TẠO RA TỪ ĐÂU?</strong></p>\r\n<p class="MsoNormal">Có 1 thành phần quan trọng trong Sql Server là <strong><span style="color: green;">Query Optimizer,</span></strong> nhiệm vụ của <strong><span style="color: green;">Query Optimizer</span></strong> là tìm ra Execution Plan được cho là là <strong><span style="color: green;">‘tốt’</span></strong>, chứ không phải <strong><span style="color: green;">‘tốt nhất’</span></strong>, vì có thể cùng một câu truy vấn, nhưng có hàng chục, hàng trăm Execution Plan khác nhau có thể được tạo ra để phục vụ câu truy vấn đó.</p>\r\n<p class="MsoNormal"><strong>EXECUTION PLAN ĐƯỢC LƯU Ở ĐÂU?</strong></p>\r\n<p class="MsoNormal">Execution Plan được lưu trong Plan Cache hay còn gọi là Procedure Cache.</p>\r\n<p class="MsoNormal">Procedure Cache và một phần trong Sql Server Buffer Cache.</p>\r\n<p class="MsoNormal">Việc lưu Plan trong bộ nhớ cho phép Sql Server tránh phải lập lại toàn bộ quy trình tối ưu câu truy vấn khi nhiều câu truy vấn giống nhau được submit.</p>\r\n<p style="text-align: right;">Quang Vinh\r\nmai.quangvinh@sqlvn.com</p>\r\n \r\n<p class="MsoNormal"> </p>\r\n\r\n</div>', '', '', 'inherit', 'open', 'open', '', '266-revision-7', '', '', '2011-04-17 14:49:53', '2011-04-17 14:49:53', '', 266, 'http://sqlvn.com/uncategorized/266-revision-7.html', 0, 'revision', '', 0);
0 comments:
Post a Comment
Click to see the code!
To insert emoticon you must added at least one space before the code.