<?xml version="1.0" encoding="UTF-8" standalone="no"?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0"><channel><title>德瑞克：SQL Server 學習筆記</title><description>滴水穿石：利用時間</description><managingEditor>noreply@blogger.com (DerrickLaLa)</managingEditor><pubDate>Sat, 28 Mar 2026 19:09:33 +0800</pubDate><generator>Blogger http://www.blogger.com</generator><openSearch:totalResults xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/">781</openSearch:totalResults><openSearch:startIndex xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/">1</openSearch:startIndex><openSearch:itemsPerPage xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/">25</openSearch:itemsPerPage><link>http://sharedderrick.blogspot.com/</link><language>en-us</language><itunes:explicit>no</itunes:explicit><itunes:subtitle>滴水穿石：利用時間</itunes:subtitle><itunes:category text="Technology"><itunes:category text="Software How-To"/></itunes:category><itunes:owner><itunes:email>noreply@blogger.com</itunes:email></itunes:owner><item><title>[Hyper-V] 安裝 Windows 11 Pro 虛擬機器（使用本機帳戶 Local Account 登入）</title><link>http://sharedderrick.blogspot.com/2025/08/hyper-v-windows-11-pro-local-account.html</link><category>Hyper_V</category><category>Windows</category><author>noreply@blogger.com (DerrickLaLa)</author><pubDate>Fri, 1 Aug 2025 16:56:00 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1420955872914622499.post-2298079144363423374</guid><description>&lt;p&gt;[Hyper-V] 安裝 Windows 11 Pro 虛擬機器（使用本機帳戶 Local Account 登入）&lt;/p&gt;&lt;p&gt;更新日期：2025/07/30&lt;/p&gt;&lt;p&gt;ISO 檔版本：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;Win11_24H2_Chinese_Traditional_x64.iso（Windows 11 24H2），是 Win11 24H2 版本。&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/a/AVvXsEhE98-5AXysI1769yOX8XvK8BV5zZl3ZaFM6l9BOe6AJ2oQsUh8gIZRsRX4uj3-tqVxrKvXZ8BIWEXUsECC00wW1JSKEwTph2m0d0gbFcojJmD-kkksbmQlg0eLOgWtGUNkoENAFZXiKtpFcFGxR6nWxPTaaZuVssSKiLEZx8kOHo46S-OmZM5EnQNii7I" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="" data-original-height="533" data-original-width="787" height="217" src="https://blogger.googleusercontent.com/img/a/AVvXsEhE98-5AXysI1769yOX8XvK8BV5zZl3ZaFM6l9BOe6AJ2oQsUh8gIZRsRX4uj3-tqVxrKvXZ8BIWEXUsECC00wW1JSKEwTph2m0d0gbFcojJmD-kkksbmQlg0eLOgWtGUNkoENAFZXiKtpFcFGxR6nWxPTaaZuVssSKiLEZx8kOHo46S-OmZM5EnQNii7I=w320-h217" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;前言&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;因測試需求，需在 Hyper-V 中安裝 Windows 11 Pro 虛擬機器。&lt;/li&gt;&lt;li&gt;本文紀錄整個安裝流程，特別是如何 跳過 Microsoft 帳號登入，改為使用 本機帳戶(Local Account) 登入。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;span&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;/span&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2 style="text-align: left;"&gt;虛擬機設定重點&lt;/h2&gt;&lt;p&gt;&lt;/p&gt;&lt;h3 style="text-align: left;"&gt;1. 虛擬機世代選擇：第 2 代&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;Windows 11 基於 UEFI 架構，需選擇 第 2 代虛擬機。&lt;/li&gt;&lt;li&gt;若選錯為第 1 代，會無法順利啟動安裝。&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/a/AVvXsEiXvwzuv_naaXI3MyBNd8UfIryA8-55lVuK8Z0sFYpdF05-jMQRz8Au4Nz-T1CEVdxMRb3EgFTqcd1lMwKlsRujmAry5u0Ixed-BYda78NBflT5TSLHQFV17v2NCNpXxB0OI1gxCzpZtmfJGYkHdNhEP92CV-Dry3cbGj6o1gkq3BVlIJ9ULZBplL6XfNw" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="" data-original-height="533" data-original-width="787" height="434" src="https://blogger.googleusercontent.com/img/a/AVvXsEiXvwzuv_naaXI3MyBNd8UfIryA8-55lVuK8Z0sFYpdF05-jMQRz8Au4Nz-T1CEVdxMRb3EgFTqcd1lMwKlsRujmAry5u0Ixed-BYda78NBflT5TSLHQFV17v2NCNpXxB0OI1gxCzpZtmfJGYkHdNhEP92CV-Dry3cbGj6o1gkq3BVlIJ9ULZBplL6XfNw=w640-h434" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h4 style="text-align: left;"&gt;2. 網路設定：未連線&lt;/h4&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;在安裝過程中，有些場景無法使用網路，或不希望強制登入 Microsoft 帳號，因此建議先設定為「未連線」。&lt;/li&gt;&lt;li&gt;後續可手動安裝虛擬交換器與網路驅動程式。&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/a/AVvXsEh7PHS2hEiNOdER4tCTCknoiSoUK_cM9AYw_rHft7JiMDNu8iaqaE9SA2BdtDOEK4zTOF7vP6izJC8lop-BbV5lTHvciq27i7WqwVy7eJbvi7LbK64GPT-cEf22uAXjewaflriMTRIUj6nMUu7jCTlzj_K6N8kV2Of7KKy4ul5kX-j0s71_2YQG2Mcp_DE" style="margin-left: auto; margin-right: auto;"&gt;&lt;img alt="" data-original-height="533" data-original-width="787" height="434" src="https://blogger.googleusercontent.com/img/a/AVvXsEh7PHS2hEiNOdER4tCTCknoiSoUK_cM9AYw_rHft7JiMDNu8iaqaE9SA2BdtDOEK4zTOF7vP6izJC8lop-BbV5lTHvciq27i7WqwVy7eJbvi7LbK64GPT-cEf22uAXjewaflriMTRIUj6nMUu7jCTlzj_K6N8kV2Of7KKy4ul5kX-j0s71_2YQG2Mcp_DE=w640-h434" width="640" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;h4 style="text-align: left;"&gt;3.&amp;nbsp;啟用信賴平台模組（TPM）以符合 Windows 11 安裝需求&lt;/h4&gt;&lt;div&gt;&lt;div&gt;在 Hyper-V 虛擬機器中安裝 Windows 11 時，若未正確設定虛擬硬體，可能會出現以下錯誤：&lt;/div&gt;&lt;div&gt;「此電腦目前不符合 Windows 11 系統需求」&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;這通常是因為虛擬機未啟用 信賴平台模組（TPM）等 Windows 11 安裝所需的條件。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/a/AVvXsEjepx_uIBQ9gtApbuQ2KZx7bJKSzYCOy1qw3b7zCHS_kY-vkCdpxZnTqUoDYEoyUFPm1Fxz-XArePIIqr_clX9vbMRvjuGf8bDTAYRYUQttF9V1VbQrQnSfydiYw-M3iTdbzXPpzcl_dNd0ah5VabtN932cdtPaHxzwDC5RKrDKr34VZ1nGE94rqpiYV4w" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="" data-original-height="703" data-original-width="897" height="502" src="https://blogger.googleusercontent.com/img/a/AVvXsEjepx_uIBQ9gtApbuQ2KZx7bJKSzYCOy1qw3b7zCHS_kY-vkCdpxZnTqUoDYEoyUFPm1Fxz-XArePIIqr_clX9vbMRvjuGf8bDTAYRYUQttF9V1VbQrQnSfydiYw-M3iTdbzXPpzcl_dNd0ah5VabtN932cdtPaHxzwDC5RKrDKr34VZ1nGE94rqpiYV4w=w640-h502" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;解決方法：啟用 TPM&amp;nbsp;（Enable Trusted Platform Module）&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;在 Hyper-V 管理員中&lt;/div&gt;&lt;div&gt;設定 [安全性]，勾選 [啟用信賴平台模組]&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/a/AVvXsEgW7lRYhAr7GFxsJvnR4cIwkWIOHt-nCqASBvcDNqEmZn9gb7kHgaB47cXMZvTeWif7QIsStZ8BoZkqnMGzO9o1SZMTrSl9Kk8CkDcgTnKqRFgUu9Q-oNK4n6_melf6MuX-FstAaKqsvu03N-gbLnvku9axCkHi8kinWQB4ngG-gSLdApeIwVQUTcV6e9w" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="" data-original-height="783" data-original-width="842" height="595" src="https://blogger.googleusercontent.com/img/a/AVvXsEgW7lRYhAr7GFxsJvnR4cIwkWIOHt-nCqASBvcDNqEmZn9gb7kHgaB47cXMZvTeWif7QIsStZ8BoZkqnMGzO9o1SZMTrSl9Kk8CkDcgTnKqRFgUu9Q-oNK4n6_melf6MuX-FstAaKqsvu03N-gbLnvku9axCkHi8kinWQB4ngG-gSLdApeIwVQUTcV6e9w=w640-h595" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;說明補充:&lt;/div&gt;&lt;div&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;TPM 2.0 是 Windows 11 強制需求之一，用於增強安全性與裝置驗證。&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;在 Hyper-V 管理員中:&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;啟用信賴平台模組（Enable Trusted Platform Module）&lt;/li&gt;&lt;li&gt;啟用安全啟動（Enable Secure Boot）啟用安全啟動（Enable Secure Boot）&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;若仍遇到問題，可一併檢查以下設定：&lt;/div&gt;&lt;div&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;虛擬處理器需至少為 2 核心&lt;/li&gt;&lt;li&gt;記憶體配置建議至少 4 GB&lt;/li&gt;&lt;li&gt;開機硬碟為 UEFI 格式（VHDX），非 MBR&lt;/li&gt;&lt;li&gt;設定 第 2 代虛擬機&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;&lt;!--more--&gt;&lt;/span&gt;&lt;h4 style="text-align: left;"&gt;4. 跳過 Microsoft 帳號登入，使用本機帳戶的操作方式&lt;/h4&gt;&lt;p&gt;在安裝過程中，預設會要求連線網路並登入 Microsoft 帳號。若要改為使用 本機帳戶 (Local Account)，請依以下步驟操作：&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;在 [這是正確的國家或地區嗎] 畫面&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;按下鍵盤快捷鍵: &lt;b&gt;Shift + F10&lt;/b&gt;&lt;/li&gt;&lt;li&gt;呼叫出 命令提示字元 視窗&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/a/AVvXsEgV1RS-6A7kNOuaO-_zU0ptTT6jQpoetIuN1nXeC-cw0PT8ElHYBzik06IoQoQGkEnI281nQa__lF-2vaONnYtgDxnjAJSUGHTnatpXWcQnqpILzfv8DUPpOtdEYt7xOXtQ5WT-N3lyv0wHRQC3ahH4560OTjaLA8eXPPEU1MVztxf8izAa4_WMGmpN7D8" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="" data-original-height="960" data-original-width="1280" height="480" src="https://blogger.googleusercontent.com/img/a/AVvXsEgV1RS-6A7kNOuaO-_zU0ptTT6jQpoetIuN1nXeC-cw0PT8ElHYBzik06IoQoQGkEnI281nQa__lF-2vaONnYtgDxnjAJSUGHTnatpXWcQnqpILzfv8DUPpOtdEYt7xOXtQ5WT-N3lyv0wHRQC3ahH4560OTjaLA8eXPPEU1MVztxf8izAa4_WMGmpN7D8=w640-h480" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;可以看到&amp;nbsp;命令提示字元 視窗&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/a/AVvXsEj6KIMieBJL8-EOOyJ-k9fjeRGCHfscAvmYbTQGPFW_GK41rBR6izrh9tKvtM80eWl1yEZSGIRsYT1i7hiOT22Kvb5Y2pfAF9bisYITzMyDQpLRcc-ku23vFb-Eis7G6zciK2fwaAdlulhM4WpyYJMQv11hcJEcz8o9S43CkB4lUFwkK66Yde_uw_7v2Xs" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="" data-original-height="960" data-original-width="1280" height="480" src="https://blogger.googleusercontent.com/img/a/AVvXsEj6KIMieBJL8-EOOyJ-k9fjeRGCHfscAvmYbTQGPFW_GK41rBR6izrh9tKvtM80eWl1yEZSGIRsYT1i7hiOT22Kvb5Y2pfAF9bisYITzMyDQpLRcc-ku23vFb-Eis7G6zciK2fwaAdlulhM4WpyYJMQv11hcJEcz8o9S43CkB4lUFwkK66Yde_uw_7v2Xs=w640-h480" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;在 命令提示字元 視窗，輸入以下指令後按下 Enter：&lt;/div&gt;&lt;div&gt;&lt;b&gt;oobe\bypassnro&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;備註&lt;/div&gt;&lt;div&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;oobe\bypassnro：解除網路要求，允許在無網路狀態下進一步選擇本機帳戶建立&lt;/li&gt;&lt;li&gt;OOBE 是什麼？&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Out‑of‑Box Experience（開箱體驗）的縮寫，指的是使用者第一次開機或啟動新裝置時，從建立帳戶、接受授權條款、選擇語言鍵盤，到連接網路與設定隱私偏好等一系列畫面與流程&amp;nbsp;&lt;/li&gt;&lt;li&gt;在 Windows 11 中，OOBE 就是第一次進入系統前的那段初始設定流程。這套流程被設計來逐步引導使用者完成必要設置，降低操作複雜性並提供清晰指示&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/a/AVvXsEhptKHTyBmL0VVf2BY94bVlY0juldM93L4Mb53xG-uF9KvpLts349kVJt8qL5La48lj10Pk2W4dqnEthRSZWgt7ms2z9Jl1xWGJ94h8ntPy9l4XZ7ozMAXT6czpUH2loatyM_iSkWvdywMHm2TRqGeHEdx9HRNaNF6fJ8OWC8k1S423xX0wpE52fClIgGE" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="" data-original-height="960" data-original-width="1280" height="480" src="https://blogger.googleusercontent.com/img/a/AVvXsEhptKHTyBmL0VVf2BY94bVlY0juldM93L4Mb53xG-uF9KvpLts349kVJt8qL5La48lj10Pk2W4dqnEthRSZWgt7ms2z9Jl1xWGJ94h8ntPy9l4XZ7ozMAXT6czpUH2loatyM_iSkWvdywMHm2TRqGeHEdx9HRNaNF6fJ8OWC8k1S423xX0wpE52fClIgGE=w640-h480" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;系統會自動重開機，重新進入 OOBE 安裝流程。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;在 [讓我們將您連線到網路] 畫面&lt;/div&gt;&lt;div&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;點選下方的 [我沒有網際網路]&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/a/AVvXsEjFAc4koxkUHeiYvcMOC9HmfzP1ynxH3IhADJ_yZ4TipAtUdGlbg6KsfIunqaCtRMW2lWajcIHq-9gfqiEcUtKb1FCF1OQSJt1386jvFggb42QEITc6Yzu_0dSGZjrfA5sqH-l0mRRp-jGYyjgE6S6n_HIk1anI5XvmCTRLQMcsjltKrxF0HgqukKwVZYs" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="" data-original-height="960" data-original-width="1280" height="480" src="https://blogger.googleusercontent.com/img/a/AVvXsEjFAc4koxkUHeiYvcMOC9HmfzP1ynxH3IhADJ_yZ4TipAtUdGlbg6KsfIunqaCtRMW2lWajcIHq-9gfqiEcUtKb1FCF1OQSJt1386jvFggb42QEITc6Yzu_0dSGZjrfA5sqH-l0mRRp-jGYyjgE6S6n_HIk1anI5XvmCTRLQMcsjltKrxF0HgqukKwVZYs=w640-h480" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;在 [誰會使用這台裝置] 畫面&lt;/div&gt;&lt;div&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;輸入 使用者帳號，也就是&amp;nbsp;本機帳戶(Local Account)&lt;/li&gt;&lt;li&gt;設定 密碼&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/a/AVvXsEiM0zT_XSxDOnyEBJvqGfZWIhtH6gw4ajnGUx_suDPxOrGbh1rpC-40hE1OicD_CPoSFBDJg4GYheFS7SMzUjlSCmgodSp9uNIMaEgfqILk-_9uN-6KnNkb0aorWuMmYSKW0AUSmeUUKs-iUaEUM9db3IXas6b8r57bMNK2ZNmX6uKwsFh8GY06FiW4sJ0" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="" data-original-height="960" data-original-width="1280" height="480" src="https://blogger.googleusercontent.com/img/a/AVvXsEiM0zT_XSxDOnyEBJvqGfZWIhtH6gw4ajnGUx_suDPxOrGbh1rpC-40hE1OicD_CPoSFBDJg4GYheFS7SMzUjlSCmgodSp9uNIMaEgfqILk-_9uN-6KnNkb0aorWuMmYSKW0AUSmeUUKs-iUaEUM9db3IXas6b8r57bMNK2ZNmX6uKwsFh8GY06FiW4sJ0=w640-h480" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;安裝完成後，可以使用&amp;nbsp;本機帳戶(Local Account) 登入到 Windows 11 系統。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/a/AVvXsEh4YyUCc7WT4_uSMV5mpQ1qT8NlZRfE_AikM3KuWHUKHOeyuXpPdXfS9FjepyxHxa9hqe3EubVVawghr1esB_Rr7bO0x8awi1h8wuDUQcGPUwQ0smwwyUfqil_D-53pXu7JFqxYTI7BDYl_gFeWbyXNPAEkSJ9wKRP0TtEP2l67qEoQfSBkr53tfILku4k" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="" data-original-height="960" data-original-width="805" height="640" src="https://blogger.googleusercontent.com/img/a/AVvXsEh4YyUCc7WT4_uSMV5mpQ1qT8NlZRfE_AikM3KuWHUKHOeyuXpPdXfS9FjepyxHxa9hqe3EubVVawghr1esB_Rr7bO0x8awi1h8wuDUQcGPUwQ0smwwyUfqil_D-53pXu7JFqxYTI7BDYl_gFeWbyXNPAEkSJ9wKRP0TtEP2l67qEoQfSBkr53tfILku4k=w536-h640" width="536" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;span&gt;&lt;!--more--&gt;&lt;/span&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;小結&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;使用 Hyper-V 安裝 Windows 11 Pro 並不複雜，但若需跳過 Microsoft 帳號強制登入，記得使用 oobe\bypassnro 指令來解鎖 本機帳戶 設定選項，這對無網路環境或測試需求是實用的。&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;span&gt;&lt;!--more--&gt;&lt;/span&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;[參考文件]&lt;/p&gt;&lt;p style="text-align: left;"&gt;&lt;/p&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;&lt;a href="https://support.microsoft.com/zh-tw/windows/windows-11%E5%AE%89%E5%85%A8%E5%95%9F%E5%8B%95-a8ff1202-c0d9-42f5-940f-843abef64fad" rel="nofollow" target="_blank"&gt;Windows 11安全啟動&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://www.microsoft.com/zh-tw/software-download/windows11" rel="nofollow" target="_blank"&gt;下載 Windows 11&lt;/a&gt;: 選擇 下載適用於 x64 裝置的 Windows 11 磁碟映像 (ISO)&lt;/li&gt;&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=SiDLgdbFdtM" rel="nofollow" target="_blank"&gt;NO Microsoft Account Needed! Windows 11 Setup Bypass (LATEST 6/2025)&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</description><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/a/AVvXsEhE98-5AXysI1769yOX8XvK8BV5zZl3ZaFM6l9BOe6AJ2oQsUh8gIZRsRX4uj3-tqVxrKvXZ8BIWEXUsECC00wW1JSKEwTph2m0d0gbFcojJmD-kkksbmQlg0eLOgWtGUNkoENAFZXiKtpFcFGxR6nWxPTaaZuVssSKiLEZx8kOHo46S-OmZM5EnQNii7I=s72-w320-h217-c" width="72"/><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><title>Install SQL Server 2019 on Windows Server 2019: 安裝抓圖</title><link>http://sharedderrick.blogspot.com/2020/04/install-sql-server-2019-on-windows.html</link><category>SQL Server 2019</category><author>noreply@blogger.com (DerrickLaLa)</author><pubDate>Wed, 22 Apr 2020 12:30:00 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1420955872914622499.post-1983184183814698670</guid><description>&lt;br /&gt;
&lt;span style="background-color: white; color: #222222; font-family: &amp;quot;arial&amp;quot; , &amp;quot;tahoma&amp;quot; , &amp;quot;helvetica&amp;quot; , &amp;quot;freesans&amp;quot; , sans-serif; font-size: 13.2px;"&gt;版本資訊：&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: white; color: #222222; font-family: &amp;quot;arial&amp;quot; , &amp;quot;tahoma&amp;quot; , &amp;quot;helvetica&amp;quot; , &amp;quot;freesans&amp;quot; , sans-serif; font-size: 13.2px;"&gt;SQL Server 2019 RTM -&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: white; font-family: &amp;quot;arial&amp;quot; , &amp;quot;tahoma&amp;quot; , &amp;quot;helvetica&amp;quot; , &amp;quot;freesans&amp;quot; , sans-serif;"&gt;&lt;span style="color: #660000;"&gt;&lt;span style="font-size: 13.2px;"&gt;&lt;b&gt;15.0.2070.41&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #222222;"&gt;&lt;span style="font-size: 13.2px;"&gt;&amp;nbsp;(X64)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;table border="1" cellpadding="1" cellspacing="1" style="background-color: white; color: #222222; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13.2px;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;div style="text-align: center;"&gt;
Build Information&lt;/div&gt;
&lt;/td&gt;&lt;td&gt;&lt;div style="text-align: center;"&gt;
Note&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;SQL Server Version&lt;/td&gt;&lt;td&gt;&lt;div style="text-align: center;"&gt;
SQL Server 2019&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Product Version&lt;/td&gt;&lt;td&gt;&lt;div style="text-align: center;"&gt;
&lt;span style="font-size: 13.2px;"&gt;15.0.2070.41&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Product Level&lt;/td&gt;&lt;td&gt;&lt;div style="text-align: center;"&gt;
RTM&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Product Edition&lt;/td&gt;&lt;td&gt;&lt;div style="text-align: center;"&gt;
Enterprise Edition (64-bit)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Database Internal Version&lt;/td&gt;&lt;td&gt;&lt;div style="text-align: center;"&gt;
904&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style="background-color: white; color: #222222; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13.2px;" /&gt;
&lt;span style="background-color: white; color: #222222; font-family: &amp;quot;arial&amp;quot; , &amp;quot;tahoma&amp;quot; , &amp;quot;helvetica&amp;quot; , &amp;quot;freesans&amp;quot; , sans-serif; font-size: 13.2px;"&gt;SQL Server 2019 的圖型介面工具：SSMS、SSDT，需要額外下載安裝。&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: white; color: #222222; font-family: &amp;quot;arial&amp;quot; , &amp;quot;tahoma&amp;quot; , &amp;quot;helvetica&amp;quot; , &amp;quot;freesans&amp;quot; , sans-serif; font-size: 13.2px;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;版本資訊&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
-- 01_SQL Server 2019 + Windows Server 2019&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbTFaQGrtB4cW3siP0MmKGyNHIr8AjfwfJJ9d0MIQc9XCrleGb5N4_XzaXzb1ZocIQ87uu-P51V7Y7iK8qy02D2XMxNebMzsFIxzvtD2GM-NyfAP9OwxPTJ_SzCeufUuz7donB5nQnXAg/s1600/51.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="161" data-original-width="1571" height="64" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbTFaQGrtB4cW3siP0MmKGyNHIr8AjfwfJJ9d0MIQc9XCrleGb5N4_XzaXzb1ZocIQ87uu-P51V7Y7iK8qy02D2XMxNebMzsFIxzvtD2GM-NyfAP9OwxPTJ_SzCeufUuz7donB5nQnXAg/s640/51.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
-- 02_資料庫相容性層級：150&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwlhnWK83jqOeE3q7j9V7xw58owgKMCnAE_kbZkBZ5fZua8kf3PcDta5rYPrl6QEcAtR_QynzeBB4jpTx1L5aEMnXZJxAGsGRoGuJK-hdm44X5MVUMin-d7JD1ylPfCN70UrK8XgtobTo/s1600/52.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="611" data-original-width="697" height="560" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwlhnWK83jqOeE3q7j9V7xw58owgKMCnAE_kbZkBZ5fZua8kf3PcDta5rYPrl6QEcAtR_QynzeBB4jpTx1L5aEMnXZJxAGsGRoGuJK-hdm44X5MVUMin-d7JD1ylPfCN70UrK8XgtobTo/s640/52.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhE7-x3gQBpIzSkJ7UbQAE6dB2Ic4CgIWnXBb1tcF8ZaOd4EeSxAzReBihVT4E0Zb6IlA_2n9LZuddnuTVdjF4PSkVwETdvCsxJLu-PJP4L3EAcuHOaht91hf-dOM0TFa6J1YQ8A1kdPSk/s1600/53.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="611" data-original-width="698" height="560" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhE7-x3gQBpIzSkJ7UbQAE6dB2Ic4CgIWnXBb1tcF8ZaOd4EeSxAzReBihVT4E0Zb6IlA_2n9LZuddnuTVdjF4PSkVwETdvCsxJLu-PJP4L3EAcuHOaht91hf-dOM0TFa6J1YQ8A1kdPSk/s640/53.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;安裝抓圖&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Install SQL Server 2019 on Windows Server 2019&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://photos.app.goo.gl/TwioHWoq2GrKnbpBA"&gt;https://photos.app.goo.gl/TwioHWoq2GrKnbpBA&lt;/a&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style="color: blue; font-size: large;"&gt;Query version, edition and update level&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
V2: Query SQL Server system and build information&lt;br /&gt;
&lt;br /&gt;
適用於 SQL Server 2019&lt;br /&gt;
加上 作業系統平台&lt;br /&gt;
使用 SQL Server 2017 新增加的 sys.dm_os_host_info&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: sql"&gt;-- V2_SQL Server system and build information
-- Applies to: SQL Server 2019
&amp;nbsp;&amp;nbsp;
SELECT @@SERVERNAME 'InstanceName',
 CASE WHEN CONVERT(VARCHAR(128), SERVERPROPERTY ('ProductVersion')) like '8%' THEN 'SQL Server 2000'
  WHEN CONVERT(VARCHAR(128), SERVERPROPERTY ('ProductVersion')) like '9%' THEN 'SQL Server 2005'
  WHEN CONVERT(VARCHAR(128), SERVERPROPERTY ('ProductVersion')) like '10.0%' THEN 'SQL Server 2008'
  WHEN CONVERT(VARCHAR(128), SERVERPROPERTY ('ProductVersion')) like '10.5%' THEN 'SQL Server 2008 R2'
  WHEN CONVERT(VARCHAR(128), SERVERPROPERTY ('ProductVersion')) like '11%' THEN 'SQL Server 2012'
  WHEN CONVERT(VARCHAR(128), SERVERPROPERTY ('ProductVersion')) like '12%' THEN 'SQL Server 2014'
  WHEN CONVERT(VARCHAR(128), SERVERPROPERTY ('ProductVersion')) like '13%' THEN 'SQL Server 2016'
  WHEN CONVERT(VARCHAR(128), SERVERPROPERTY ('ProductVersion')) like '14%' THEN 'SQL Server 2017'
  WHEN CONVERT(VARCHAR(128), SERVERPROPERTY ('ProductVersion')) like '15%' THEN 'SQL Server 2019'
  ELSE 'unknown'
  END AS 'SQLServerVersion ', 
 CASE WHEN SERVERPROPERTY('IsClustered') = 1 AND SERVERPROPERTY('IsHadrEnabled') = 1 THEN 'Failover Cluster + Availability Groups'
  WHEN SERVERPROPERTY('IsClustered') = 1 THEN 'Failover Cluster'
  WHEN SERVERPROPERTY('IsHadrEnabled') =1 THEN 'Availability Groups'
  ELSE 'unknown'
 END AS 'High-Availability', 
 host_distribution 'HostDistribution', host_release 'HostRelease',
 SERVERPROPERTY('ProductVersion') 'ProductVersion',
 SERVERPROPERTY('ProductLevel') 'ProductLevel',
 SERVERPROPERTY('Edition') 'ProductEdition',
 SERVERPROPERTY('ProductUpdateLevel') 'ProductUpdateLevel', 
 SERVERPROPERTY('ProductBuildType') 'ProductBuildType', 
 SERVERPROPERTY('ProductUpdateReference') 'ProductUpdateReference', 
 DATABASEPROPERTYEX('master','Version') 'DatabaseInternalVersion'
FROM sys.dm_os_host_info 
GO
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
Reference&lt;br /&gt;
&lt;br /&gt;
Install SQL Server 2017 on Windows Server 2016&lt;br /&gt;
&lt;a href="https://sharedderrick.blogspot.com/2017/10/install-sql-server-2017-on-windows.html"&gt;https://sharedderrick.blogspot.com/2017/10/install-sql-server-2017-on-windows.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
[SQL Server] Query version, edition and update level - 版本、版次、編號&lt;br /&gt;
&lt;a href="https://sharedderrick.blogspot.com/2017/08/sql-server-query-version-edition-and.html"&gt;https://sharedderrick.blogspot.com/2017/08/sql-server-query-version-edition-and.html&lt;/a&gt;&lt;br /&gt;
&lt;iframe class="ginger-extension-definitionpopup" style="display: none;"&gt;&lt;/iframe&gt;</description><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbTFaQGrtB4cW3siP0MmKGyNHIr8AjfwfJJ9d0MIQc9XCrleGb5N4_XzaXzb1ZocIQ87uu-P51V7Y7iK8qy02D2XMxNebMzsFIxzvtD2GM-NyfAP9OwxPTJ_SzCeufUuz7donB5nQnXAg/s72-c/51.png" width="72"/><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><title>Sysprep 變更 SID(Security Identifier)，以 Windows Server 2019 為例</title><link>http://sharedderrick.blogspot.com/2020/04/sysprep-sidsecurity-identifier-windows.html</link><category>Windows Server 2019</category><author>noreply@blogger.com (DerrickLaLa)</author><pubDate>Tue, 21 Apr 2020 08:30:00 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1420955872914622499.post-3860325387693957280</guid><description>Sysprep 變更SID(Security Identifier)，以 Windows Server 2019 為例&lt;br /&gt;
&lt;br /&gt;
在使用虛擬機器時，採取「複製虛擬機器」的方式來建置多台虛擬機器，可簡化安裝建置的時間。&lt;br /&gt;
&lt;br /&gt;
但每台虛擬機器的電腦安全性識別碼(SID，Security Identifie)，因為採取複製方式，導致其電腦安全性識別碼都重複相同。&lt;br /&gt;
&lt;br /&gt;
影響&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;這個問題會影響到各種工作群組環境中的安全性，而且卸除式媒體安全性在具有多重相同電腦 SID 的網路中也會受到影響。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
使用系統準備(Sysprep)工具，會將電腦設定為重新開機時，建立新的電腦安全性識別碼(SID)。&lt;br /&gt;
&lt;br /&gt;
系統準備(Sysprep)的功能&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;從 Windows 映像中移除電腦特定的資訊，包括電腦的安全識別碼（SID）。 這可讓您捕獲映射並將它套用到其他電腦。 這就是所謂的電腦一般化(generalizing)。&lt;/li&gt;
&lt;li&gt;從 Windows 映像卸載電腦特有的驅動程式。&lt;/li&gt;
&lt;li&gt;將電腦設定為開機至 OOBE，以準備電腦以傳遞給客戶。&lt;/li&gt;
&lt;li&gt;可讓您將回應檔案（自動安裝）設定新增至現有的安裝。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
注意事項&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;在完成變更SID(Security Identifier)後，系統相關的組態會重置，例如：&lt;/li&gt;
&lt;li&gt;設定時區、鍵盤、電腦名稱、登入帳戶的密碼、「Windows 需要重新啟用」等。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;Sysprep 圖形化使用者介面&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
示範環境：&lt;br /&gt;
Windows Server 2019 Datacenter 版本。&lt;br /&gt;
&lt;br /&gt;
-- 01_使用whoami，user參數，查詢SID&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgd2oJmyAX3ETG-zY7KfYlJNsnEv5JbCQGazPSEJ1psQ74GqwpJeHbmt0qNqoQlulFDJ6VPKMOWPPUQfGruW-nolC1lVzCzYXZeMJA-wLOY8aOBEtTzGjbUA1XNfLhCShtxy7kXX46AeQ/s1600/01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="768" data-original-width="1024" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgd2oJmyAX3ETG-zY7KfYlJNsnEv5JbCQGazPSEJ1psQ74GqwpJeHbmt0qNqoQlulFDJ6VPKMOWPPUQfGruW-nolC1lVzCzYXZeMJA-wLOY8aOBEtTzGjbUA1XNfLhCShtxy7kXX46AeQ/s640/01.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
-- 02_使用檔案總管，執行C:\Windows\System32\Sysprep目錄下的Sysprep.exe。&lt;br /&gt;
&lt;br /&gt;
使用參數：&lt;br /&gt;
系統清理動作：進入系統全新體驗(ODBE)。&lt;br /&gt;
勾選：一般化。&lt;br /&gt;
關機選項：重新開機。&lt;br /&gt;
&lt;br /&gt;
Sysprep 會重設安全性識別碼 (SID)，清除任何系統還原點以及刪除事件記錄檔&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMfXx_fwDCkdQiGGlaclEEx7Le9HOTzykQvJJBH7nkUY34zC3wzJuoyYcZ5vnwwkC9OjWiaBVfXr2EuPW6KbceoMfc1kvQdGt1NXpAFfvxmFBe5Mq1MnWC9FeBJWUCDXf0qekplP-RLRQ/s1600/02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="768" data-original-width="1024" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMfXx_fwDCkdQiGGlaclEEx7Le9HOTzykQvJJBH7nkUY34zC3wzJuoyYcZ5vnwwkC9OjWiaBVfXr2EuPW6KbceoMfc1kvQdGt1NXpAFfvxmFBe5Mq1MnWC9FeBJWUCDXf0qekplP-RLRQ/s640/02.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRSVLuvd9UsnKhuDNXMkBRrso5QVAol_wn1RwM6GWhfLev9H7qgu-rYX7OwOI7vmVHakvNJ7yD3C7BM6qOnfR4oj8iJx5hFQC4vrQFS608o0EKkU9hcbUR1u4GPilHN9nJVjAPw-L7XIg/s1600/03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="768" data-original-width="1024" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRSVLuvd9UsnKhuDNXMkBRrso5QVAol_wn1RwM6GWhfLev9H7qgu-rYX7OwOI7vmVHakvNJ7yD3C7BM6qOnfR4oj8iJx5hFQC4vrQFS608o0EKkU9hcbUR1u4GPilHN9nJVjAPw-L7XIg/s640/03.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmkem5IG1sau4PqhjRhRKV_OAohRLcyvnsl6G_LEvHlEzs8MvAiFSHXvFocx_SHkT_50tFleABKbHZVS6V2-SnqlSLavmWKoh33KQjhyGGJrO_06kS9Wo7bbSJ_8gsLcPN3XpCKOXk2rY/s1600/04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="768" data-original-width="1024" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmkem5IG1sau4PqhjRhRKV_OAohRLcyvnsl6G_LEvHlEzs8MvAiFSHXvFocx_SHkT_50tFleABKbHZVS6V2-SnqlSLavmWKoh33KQjhyGGJrO_06kS9Wo7bbSJ_8gsLcPN3XpCKOXk2rY/s640/04.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4zCVOdBu2ddCYepwiWBkKONz6VvOKO7Prx1iWBZXNUdxW-G6gZUwkWkPKgjitYPvnY1SYSuilkO_nHUIQMQ2wtjBlMyDhx7nUa4aYV6aRmW50hbhBzsSjHWMVMt9OcTQ6VQSRG5m4vVo/s1600/05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="768" data-original-width="1024" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4zCVOdBu2ddCYepwiWBkKONz6VvOKO7Prx1iWBZXNUdxW-G6gZUwkWkPKgjitYPvnY1SYSuilkO_nHUIQMQ2wtjBlMyDhx7nUa4aYV6aRmW50hbhBzsSjHWMVMt9OcTQ6VQSRG5m4vVo/s640/05.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTrADqq88PZw8HxHYfHQ5nSyn82NYZ5KfXmsg8r8ymg8YDz8L9Ehg7WEvb49DNUEjAj6jGB8FR-GfsLNWI8p_BZ9dhLCx0DTIcm5eaPAQzgU4WiXURIN35eiulbeXX7snn9lDRirMTJIw/s1600/06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="768" data-original-width="1024" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTrADqq88PZw8HxHYfHQ5nSyn82NYZ5KfXmsg8r8ymg8YDz8L9Ehg7WEvb49DNUEjAj6jGB8FR-GfsLNWI8p_BZ9dhLCx0DTIcm5eaPAQzgU4WiXURIN35eiulbeXX7snn9lDRirMTJIw/s640/06.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
-- 03_再度使用whoami查詢，觀察到：電腦名稱、安全性識別碼 (SID)等，都已經重設。&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiM9ZUc7q92xc3FP_UZpfIM_HcYvCr08F54_mj1idy4R03ge1MVWU6MzgR0Xf9jNGp9tJ3m72drfcEGVlbdgFMoxHA2XTEZPa2Vd0Cl5c_JAZNb_uMcIeGQr7PZbEFkOAK-rKTHer-fZss/s1600/07.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="768" data-original-width="1024" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiM9ZUc7q92xc3FP_UZpfIM_HcYvCr08F54_mj1idy4R03ge1MVWU6MzgR0Xf9jNGp9tJ3m72drfcEGVlbdgFMoxHA2XTEZPa2Vd0Cl5c_JAZNb_uMcIeGQr7PZbEFkOAK-rKTHer-fZss/s640/07.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzYxUI2_JoaiU4Kh54oMg3ow7FccPHRN1GzbymsQxURozxoBGaAD2q1tYKPLNWu1fbC9abP2fT-GWkCR5seew8XN__oJoVTx89fkKohjJd34yPQN8pJBsMPEvH6LLvSBeeslI8L4h443A/s1600/21.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="768" data-original-width="1024" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzYxUI2_JoaiU4Kh54oMg3ow7FccPHRN1GzbymsQxURozxoBGaAD2q1tYKPLNWu1fbC9abP2fT-GWkCR5seew8XN__oJoVTx89fkKohjJd34yPQN8pJBsMPEvH6LLvSBeeslI8L4h443A/s640/21.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbXIkzw5Llq1ZKo6cn4uTOvNwXa4CsnvW7Z8jgWpSgkueLMfXZHCVU8ya3NiLUwV7Y8vvc-T7wv2-mnKjLjF2i-kJiD5_K_72y9_4C-KoeNvqcoXK2fKuZEnuuvJ1RYKE_YWpjBqjddRU/s1600/22.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="768" data-original-width="1024" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbXIkzw5Llq1ZKo6cn4uTOvNwXa4CsnvW7Z8jgWpSgkueLMfXZHCVU8ya3NiLUwV7Y8vvc-T7wv2-mnKjLjF2i-kJiD5_K_72y9_4C-KoeNvqcoXK2fKuZEnuuvJ1RYKE_YWpjBqjddRU/s640/22.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
參考資料&lt;br /&gt;
&lt;br /&gt;
Sysprep 圖形化使用者介面，變更SID(Security Identifier)，以 Windows Server 2016 為例&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2017/02/sysprep-sidsecurity-identifier-windows.html"&gt;http://sharedderrick.blogspot.com/2017/02/sysprep-sidsecurity-identifier-windows.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Sysprep 命令列，變更SID，以 Windows Server 2016 為例&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2017/02/sysprep-sid-windows-server-2016.html"&gt;http://sharedderrick.blogspot.com/2017/02/sysprep-sid-windows-server-2016.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Sysprep （系統準備）總覽&lt;br /&gt;
&lt;a href="https://docs.microsoft.com/zh-tw/windows-hardware/manufacture/desktop/sysprep--system-preparation--overview"&gt;https://docs.microsoft.com/zh-tw/windows-hardware/manufacture/desktop/sysprep--system-preparation--overview&lt;/a&gt;</description><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgd2oJmyAX3ETG-zY7KfYlJNsnEv5JbCQGazPSEJ1psQ74GqwpJeHbmt0qNqoQlulFDJ6VPKMOWPPUQfGruW-nolC1lVzCzYXZeMJA-wLOY8aOBEtTzGjbUA1XNfLhCShtxy7kXX46AeQ/s72-c/01.png" width="72"/><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><title>Windows server 2019 安裝</title><link>http://sharedderrick.blogspot.com/2020/04/windows-server-2019-installation.html</link><category>Windows Server 2019</category><author>noreply@blogger.com (DerrickLaLa)</author><pubDate>Mon, 20 Apr 2020 20:20:00 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1420955872914622499.post-8750775267289060183</guid><description>&lt;br /&gt;
在 Windows Server 2019&amp;nbsp;Datacenter 版本上設定基礎環境，準備作為安裝 SQL Server 2019 版本之用&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxdn1nAyOXOJbetzNdjRG5ilxDjCg-Fo_dngU5T6u9OgKcpaTaWapwl2JTkGLBQmvtxfPFSqrLCSUW3m_gclvNUPDZR3O7z3EvSxIu64oHQ5eRYy3jk86xrj6X3MSIdqll8uJGKlmDPRQ/s1600/18.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="768" data-original-width="1024" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxdn1nAyOXOJbetzNdjRG5ilxDjCg-Fo_dngU5T6u9OgKcpaTaWapwl2JTkGLBQmvtxfPFSqrLCSUW3m_gclvNUPDZR3O7z3EvSxIu64oHQ5eRYy3jk86xrj6X3MSIdqll8uJGKlmDPRQ/s640/18.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiASWMfk1SrW38U5eXofxd1oJZv4xn0s3NGChtWAnHLaqgobkJpfYJpdUaLch9WAsew7CL8qPiT8P8npvk6_2G_8P9pb-1kG-JaJXr6FUIJ1tbzE9qeAY6GrxJTnwmPMCS6_B5bQqJ1CZM/s1600/25.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="768" data-original-width="1024" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiASWMfk1SrW38U5eXofxd1oJZv4xn0s3NGChtWAnHLaqgobkJpfYJpdUaLch9WAsew7CL8qPiT8P8npvk6_2G_8P9pb-1kG-JaJXr6FUIJ1tbzE9qeAY6GrxJTnwmPMCS6_B5bQqJ1CZM/s640/25.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
版本：Windows Server 2019 Datacenter&lt;br /&gt;
編號：10.0.17763.1098&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjB1klRQuGcK-eo9TSk1hqJPgecc4G9_fIYhgVfYMJqicxYHje8Bs-rdRzpOiJhyG_hFGAN2dZh_pQ4YZCAhJyRKQBWxC8y8QktccduF6VJHryasAYMIoDUybRJYc5nKJd32oGI0WrMR7g/s1600/26.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="768" data-original-width="1024" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjB1klRQuGcK-eo9TSk1hqJPgecc4G9_fIYhgVfYMJqicxYHje8Bs-rdRzpOiJhyG_hFGAN2dZh_pQ4YZCAhJyRKQBWxC8y8QktccduF6VJHryasAYMIoDUybRJYc5nKJd32oGI0WrMR7g/s640/26.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;安裝歷程的抓圖&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://photos.app.goo.gl/pXy5wueKYuCG58NE6"&gt;https://photos.app.goo.gl/pXy5wueKYuCG58NE6&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;iframe class="ginger-extension-definitionpopup" style="display: none;"&gt;&lt;/iframe&gt;</description><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxdn1nAyOXOJbetzNdjRG5ilxDjCg-Fo_dngU5T6u9OgKcpaTaWapwl2JTkGLBQmvtxfPFSqrLCSUW3m_gclvNUPDZR3O7z3EvSxIu64oHQ5eRYy3jk86xrj6X3MSIdqll8uJGKlmDPRQ/s72-c/18.png" width="72"/><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><title>Enabled SET XACT_ABORT ON in SSMS, 在 SSMS 啟用 XACT_ABORT</title><link>http://sharedderrick.blogspot.com/2018/12/enabled-set-xactabort-on-in-ssms-ssms.html</link><category>SQL Server</category><author>noreply@blogger.com (DerrickLaLa)</author><pubDate>Sat, 1 Dec 2018 18:03:00 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1420955872914622499.post-3711120841923622213</guid><description>&lt;br /&gt;
&lt;br /&gt;
延續前一篇文章：&lt;a href="http://sharedderrick.blogspot.com/2018/11/begin-tran-with-xactabort.html"&gt;BEGIN TRAN with XACT_ABORT&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
若需要以此 SSMS 為單元，所建立的 Connection，都要啟用&amp;nbsp;XACT_ABORT，可以在 SSMS 執行以下設定&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1_8Miz1F5dAaEOhyg68ZfU7l7wbb4ZThNhRBCa9NDMALiJyLaxsY2wIv0KwsCxqX0cMgU8eUEa7pfZnmraSWCjB6keCMqwpXhFmuNIIeelvOaVu_CxP-s5x6sKYY102vci4DQssF2Wds/s1600/81_SSMS_SET_XACT_ABORT_ON.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="628" data-original-width="801" height="500" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1_8Miz1F5dAaEOhyg68ZfU7l7wbb4ZThNhRBCa9NDMALiJyLaxsY2wIv0KwsCxqX0cMgU8eUEa7pfZnmraSWCjB6keCMqwpXhFmuNIIeelvOaVu_CxP-s5x6sKYY102vci4DQssF2Wds/s640/81_SSMS_SET_XACT_ABORT_ON.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
影響範圍&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;啟用後，僅套用在此 SSMS 新建立的 Connection，不影響 SQL Server。&lt;/li&gt;
&lt;li&gt;由此 SSMS 新建立的 Connection，即刻適用。但對既有的 Connection 則不受影響。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
若有需要，可以關閉 SSMS，再度開啟 SSMS。&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Enabled SET XACT_ABORT ON in SSMS,&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;在 SSMS 啟用 XACT_ABORT&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
01. 在 SSMS ，點選上方工具選單，Tools ，選擇 Options。&lt;br /&gt;
&lt;br /&gt;
02. 在 Options 視窗&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;點選 Query Execution，SQL&amp;nbsp; Server，Advanced。&lt;/li&gt;
&lt;li&gt;或是，在 Search Options 方塊，輸入： XACT 關鍵字。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 在 Advanced \ Specify the advanced execution settings 對話方塊&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;勾選: SET XACT_ABORT ON&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure 01_SSMS_SET_XACT_ABORT_ON&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0Mii8D9ZRS3iPTMG4NOJJzuXAHqPauem-VH17556v1BD_L4ZrZZ4qstlBjOb4iPjZ7UrCgJHMFj-ubwWN4nPkvuAlOYHl8BU6KS3hN18tafEat6okfOj2Iwg-78xA7B4ECNeN2zW-C-c/s1600/81_SSMS_SET_XACT_ABORT_ON.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="628" data-original-width="801" height="500" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0Mii8D9ZRS3iPTMG4NOJJzuXAHqPauem-VH17556v1BD_L4ZrZZ4qstlBjOb4iPjZ7UrCgJHMFj-ubwWN4nPkvuAlOYHl8BU6KS3hN18tafEat6okfOj2Iwg-78xA7B4ECNeN2zW-C-c/s640/81_SSMS_SET_XACT_ABORT_ON.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
影響範圍&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;啟用後，僅套用在此 SSMS 新發出的 Connection，不影響 SQL Server。&lt;/li&gt;
&lt;li&gt;由此 SSMS 發出的新 Connection，即刻適用。但對既有的 Connection 則不受影響。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
若有需要，可以關閉 SSMS，再度開啟 SSMS。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Reference&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
BEGIN TRAN with XACT_ABORT&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/11/begin-tran-with-xactabort.html"&gt;http://sharedderrick.blogspot.com/2018/11/begin-tran-with-xactabort.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
查詢是否有啟用 XACT_ABORT 選項&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2008/09/xactabort.html"&gt;http://sharedderrick.blogspot.com/2008/09/xactabort.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
設定 user options 伺服器組態選項&lt;br /&gt;
&lt;a href="https://docs.microsoft.com/zh-tw/sql/database-engine/configure-windows/configure-the-user-options-server-configuration-option?view=sql-server-2017"&gt;https://docs.microsoft.com/zh-tw/sql/database-engine/configure-windows/configure-the-user-options-server-configuration-option?view=sql-server-2017&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
SET XACT_ABORT (Transact-SQL)&lt;br /&gt;
&lt;a href="https://docs.microsoft.com/zh-tw/sql/t-sql/statements/set-xact-abort-transact-sql?view=sql-server-2017"&gt;https://docs.microsoft.com/zh-tw/sql/t-sql/statements/set-xact-abort-transact-sql?view=sql-server-2017&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
@@TRANCOUNT (Transact-SQL)&lt;br /&gt;
&lt;a href="https://docs.microsoft.com/zh-tw/sql/t-sql/functions/trancount-transact-sql?view=sql-server-2017"&gt;https://docs.microsoft.com/zh-tw/sql/t-sql/functions/trancount-transact-sql?view=sql-server-2017&lt;/a&gt;</description><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1_8Miz1F5dAaEOhyg68ZfU7l7wbb4ZThNhRBCa9NDMALiJyLaxsY2wIv0KwsCxqX0cMgU8eUEa7pfZnmraSWCjB6keCMqwpXhFmuNIIeelvOaVu_CxP-s5x6sKYY102vci4DQssF2Wds/s72-c/81_SSMS_SET_XACT_ABORT_ON.png" width="72"/><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><title>BEGIN TRAN with XACT_ABORT</title><link>http://sharedderrick.blogspot.com/2018/11/begin-tran-with-xactabort.html</link><category>SQL Server</category><author>noreply@blogger.com (DerrickLaLa)</author><pubDate>Tue, 27 Nov 2018 22:12:00 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1420955872914622499.post-7844415457990146552</guid><description>&lt;br /&gt;
&lt;br /&gt;
若需求是&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;遇到執行階段的錯誤，希望系統能自動回復 Rollback 整個 交易 Transaction。&lt;/li&gt;
&lt;li&gt;則 請使用 BEGIN TRAN 並且設定 SET XACT_ABORT ON。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
當 SET XACT_ABORT 是 ON 時，如果 Transact-SQL 陳述式產生執行階段錯誤，就會終止和回復整個交易。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;例如：資料表不存在、違反 外部索引鍵 等。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
有啟用 SET XACT_ABORT ON，當遇到 執行階段錯誤時，系統自動回復 Rollback 目前交易，查詢 @@TRANCOUNT = 0。&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5Re9d4O6J8_ggU7ijG-kebvLMbV-jrj-AJWByCZ2IzpKYUbxM0B2gd3Isfs7l30ScBiBehEJqLVITTvIw0tae9aAR5ZECAriRgRKmXRr5jpRh1JAH1fH-0KJl0qwd7_RpJ6lA7s6P7QU/s1600/21_Compare.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="468" data-original-width="1463" height="204" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5Re9d4O6J8_ggU7ijG-kebvLMbV-jrj-AJWByCZ2IzpKYUbxM0B2gd3Isfs7l30ScBiBehEJqLVITTvIw0tae9aAR5ZECAriRgRKmXRr5jpRh1JAH1fH-0KJl0qwd7_RpJ6lA7s6P7QU/s640/21_Compare.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;BEGIN TRAN with enable XACT_ABORT&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
當 SET XACT_ABORT 是 ON 時，&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;如果 Transact-SQL 陳述式產生執行階段錯誤，就會終止和回復整個交易。&lt;/li&gt;
&lt;li&gt;例如：資料表不存在、違反 外部索引鍵 等&lt;/li&gt;
&lt;li&gt;SET XACT_ABORT 不會影響到如語法錯誤之類的編譯錯誤。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
01. 僅使用 &lt;span style="color: blue;"&gt;BEGIN TRAN&lt;/span&gt;，執行 Script:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;資料表 Products 存在，第 1 句 SELECT 執行成功，有回傳資料。&lt;/li&gt;
&lt;li&gt;但 SELECT 資料表 Products_XXX &lt;span style="color: red;"&gt;不存在&lt;/span&gt;，執行時系統回傳 Error Message 208: Invalid object name。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
問題：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;第 2 句 SELECT 執行失敗，但先前已經啟用 BEGIN TRAN，這會造成什麼影響呢？&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;01_BEGIN TRAN without XACT_ABORT&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxUPz5jZeMZcWe0Q9VQyzrU3lj4fs3waJBeH3zShqmAaJ_1Z1sQaoagClmh0iAjyrjuVlJ7bxStAATcSAOdxBcQh2_EQYiqidIsQnVANX7wBHmX8eMlTVjvDltrsf75aRBHbPmmK5RwVk/s1600/01_BEGIN+TRAN+without+XACT_ABORT.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="359" data-original-width="706" height="324" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxUPz5jZeMZcWe0Q9VQyzrU3lj4fs3waJBeH3zShqmAaJ_1Z1sQaoagClmh0iAjyrjuVlJ7bxStAATcSAOdxBcQh2_EQYiqidIsQnVANX7wBHmX8eMlTVjvDltrsf75aRBHbPmmK5RwVk/s640/01_BEGIN+TRAN+without+XACT_ABORT.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 使用 @@TRANCOUNT ，檢視目前連線已經啟用 BEGIN TRAN 的數量。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&amp;nbsp;回傳 &lt;b style="color: red;"&gt;1&lt;/b&gt;，表示已經有 1 個 BEGIN TRAN&amp;nbsp;存在。&lt;/li&gt;
&lt;li&gt;若沒有 BEGIN TRAN，預設回傳 0。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;02_Have opened a transaction, @@TRANCOUNT = 1&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDC0kxfsC7vIBH677Z1Nd_zzKsT6iT7uZ_RKugvzSl8hbi-gWCUaLtzUnt0_FDGhkE5SFNsF5-02efCb-uDegc70a36gK4kHZLQ7oLoYSIonR1nrFqVlIf0PkibOi0E_VYvqSJCAFkQbM/s1600/02_Have+opened+a+transaction.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="217" data-original-width="754" height="184" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDC0kxfsC7vIBH677Z1Nd_zzKsT6iT7uZ_RKugvzSl8hbi-gWCUaLtzUnt0_FDGhkE5SFNsF5-02efCb-uDegc70a36gK4kHZLQ7oLoYSIonR1nrFqVlIf0PkibOi0E_VYvqSJCAFkQbM/s640/02_Have+opened+a+transaction.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 若嘗試去關閉該連線。&lt;br /&gt;
&lt;br /&gt;
在 SSMS 產生警示的對話方塊，該連線有 未認可的交易(uncommitted transaction)。&lt;br /&gt;
點選 No，可以 退回 Rollback Transaction。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;03_Get_uncommitted_transaction&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZTVPM4A65nK4V_3G5O5BD4M1tMu5nbx6Dy-H8dHJQQCCL-L0kXyuIPYSLNWeP2iouQbzseF-MPf69EbBk96d-oLGeH2QkN_L6A341pt0-Grq6pyXPIIs0cw0ZPHa6sV8I3iZb0cuUm4A/s1600/03_Get_uncommitted_transaction.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="583" data-original-width="891" height="418" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZTVPM4A65nK4V_3G5O5BD4M1tMu5nbx6Dy-H8dHJQQCCL-L0kXyuIPYSLNWeP2iouQbzseF-MPf69EbBk96d-oLGeH2QkN_L6A341pt0-Grq6pyXPIIs0cw0ZPHa6sV8I3iZb0cuUm4A/s640/03_Get_uncommitted_transaction.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;BEGIN TRAN with SET XACT_ABORT ON&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
當 SET XACT_ABORT 是 ON 時，&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;如果 Transact-SQL 陳述式產生執行階段錯誤，就會終止和回復整個交易。&lt;/li&gt;
&lt;li&gt;例如：資料表不存在、違反 外部索引鍵 等&lt;/li&gt;
&lt;li&gt;SET XACT_ABORT 不會影響到如語法錯誤之類的編譯錯誤。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
01. 在新的連線上，使用 &lt;span style="color: blue;"&gt;SET XACT_ABORT ON&lt;/span&gt; 與 BEGIN TRAN。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;資料表 Products 存在，第 1 句 SELECT 執行成功，有回傳資料。&lt;/li&gt;
&lt;li&gt;但 SELECT 資料表 Products_XXX &lt;span style="color: red;"&gt;不存在&lt;/span&gt;，執行時系統回傳 Error Message 208: Invalid object name。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
問題：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;先前已經使用&amp;nbsp;SET XACT_ABORT ON 與 BEGIN TRAN。其中，第 2 句 SELECT 因資料表 不存在 而執行失敗，這會造成什麼影響呢？&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;11_Get_Error&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKsJrFSX47_4oFduCMpt8v5FQq1l1Jp5yByC6VRE1iyypam8W8WDLGXkJ6zQ5i0vd9GaUHfMpCBSmOdGihImRqpE7zim1chTIQIQrfBdy1lZ_pz6Ishsgr8NrR2cVHSDaUmKGz7iSjnmA/s1600/11_Get_Error.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="420" data-original-width="709" height="378" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKsJrFSX47_4oFduCMpt8v5FQq1l1Jp5yByC6VRE1iyypam8W8WDLGXkJ6zQ5i0vd9GaUHfMpCBSmOdGihImRqpE7zim1chTIQIQrfBdy1lZ_pz6Ishsgr8NrR2cVHSDaUmKGz7iSjnmA/s640/11_Get_Error.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 使用 @@TRANCOUNT ，檢視目前連線已經啟用 BEGIN TRAN 的數量。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&amp;nbsp;回傳&lt;span style="color: blue;"&gt; 0&lt;/span&gt;，表示沒有任何 BEGIN TRAN 存在。&lt;/li&gt;
&lt;li&gt;若沒有 BEGIN TRAN，預設回傳 0。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
這是因為當 SET XACT_ABORT 是 ON 時，&lt;br /&gt;
如果 Transact-SQL 陳述式產生執行階段錯誤，就會終止和回復整個交易。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;12_ @@TRANCOUNT = 0&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYN6BPsr-MiRyxoasHFaYBVa0_TU9EtJhhqnkvXPYI6eT5HkITahEOpAzm317fC7W_A53ItUP9CffCFB6EcbW43LMMsN4dB0V7S1bHfgUeRIt2munkTKjYPyVuqVDywN6k_hg84mYMJ9c/s1600/12_without_transaction.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="247" data-original-width="739" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYN6BPsr-MiRyxoasHFaYBVa0_TU9EtJhhqnkvXPYI6eT5HkITahEOpAzm317fC7W_A53ItUP9CffCFB6EcbW43LMMsN4dB0V7S1bHfgUeRIt2munkTKjYPyVuqVDywN6k_hg84mYMJ9c/s640/12_without_transaction.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 對比兩者的差異&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;兩邊 SQL Script 執行後，在第 2 句 SELECT 資料表 Products_XXX 不存在，系統回傳 Error Message 208: Invalid object name。&lt;/li&gt;
&lt;li&gt;有啟用&amp;nbsp;SET XACT_ABORT ON，當遇到&amp;nbsp;執行階段錯誤時，系統自動回復 Rollback 目前交易，查詢&amp;nbsp;@@TRANCOUNT = 0。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;21_Compare&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivinchO72cKzAvNuoiW0jbMHJNLZnLtqMiAIVUDEVKm8ALUXSkk031YI4nbSZ3bk2m1GwRcMOY7w0R9YyySezGmkW4ex-9gGsexW_ZLzInUhY-UjHnc7tS43I64jefhBt2ZWTSjy9aIf8/s1600/21_Compare.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="468" data-original-width="1463" height="204" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivinchO72cKzAvNuoiW0jbMHJNLZnLtqMiAIVUDEVKm8ALUXSkk031YI4nbSZ3bk2m1GwRcMOY7w0R9YyySezGmkW4ex-9gGsexW_ZLzInUhY-UjHnc7tS43I64jefhBt2ZWTSjy9aIf8/s640/21_Compare.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;hr /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Sample Code&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
20181126_BEGIN TRAN with XACT_ABORT&lt;/div&gt;
&lt;div&gt;
&lt;a href="https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing"&gt;https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;hr /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Reference&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
SET XACT_ABORT (Transact-SQL)&lt;/div&gt;
&lt;div&gt;
&lt;a href="https://docs.microsoft.com/zh-tw/sql/t-sql/statements/set-xact-abort-transact-sql?view=sql-server-2017"&gt;https://docs.microsoft.com/zh-tw/sql/t-sql/statements/set-xact-abort-transact-sql?view=sql-server-2017&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
@@TRANCOUNT (Transact-SQL)&lt;/div&gt;
&lt;div&gt;
&lt;a href="https://docs.microsoft.com/zh-tw/sql/t-sql/functions/trancount-transact-sql?view=sql-server-2017"&gt;https://docs.microsoft.com/zh-tw/sql/t-sql/functions/trancount-transact-sql?view=sql-server-2017&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
查詢是否有啟用 XACT_ABORT 選項&lt;/div&gt;
&lt;div&gt;
&lt;a href="http://sharedderrick.blogspot.com/2008/09/xactabort.html"&gt;http://sharedderrick.blogspot.com/2008/09/xactabort.html&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
設定 user options 伺服器組態選項&lt;/div&gt;
&lt;div&gt;
&lt;a href="https://docs.microsoft.com/zh-tw/sql/database-engine/configure-windows/configure-the-user-options-server-configuration-option?view=sql-server-2017"&gt;https://docs.microsoft.com/zh-tw/sql/database-engine/configure-windows/configure-the-user-options-server-configuration-option?view=sql-server-2017&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
</description><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5Re9d4O6J8_ggU7ijG-kebvLMbV-jrj-AJWByCZ2IzpKYUbxM0B2gd3Isfs7l30ScBiBehEJqLVITTvIw0tae9aAR5ZECAriRgRKmXRr5jpRh1JAH1fH-0KJl0qwd7_RpJ6lA7s6P7QU/s72-c/21_Compare.png" width="72"/><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><title>Find out Statistics used to Execution Plan from Plan Cache - DBCC TRACEON(8666), 由 Plan Cache 取得 執行計畫 所使用的 統計值</title><link>http://sharedderrick.blogspot.com/2018/10/find-out-statistics-used-to-execution_29.html</link><category>Performance Tuning</category><category>SQL Server</category><author>noreply@blogger.com (DerrickLaLa)</author><pubDate>Mon, 29 Oct 2018 20:33:00 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1420955872914622499.post-4933357434981985747</guid><description>&lt;br /&gt;
&lt;br /&gt;
啟用 TRACEON(&lt;span style="color: blue;"&gt;8666&lt;/span&gt;) 後，在 該 Session 就可以:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;由 Plan Cache (Memory) 取得 Execution Plan 所使用的 Statistics&lt;/li&gt;
&lt;li&gt;由 Include Actual Execution Plan / Display Estimated Execution Plan ，取得 Execution Plan 所使用的 Statistics&lt;/li&gt;
&lt;li&gt;在 Execution Plan 上會額外提供 Internal Debugging Information(內部偵錯用訊息) ，這包含了 Statistics 細節資訊。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
例如，可以取得:&lt;br /&gt;
StatName、ColName、ModCtr、RowCount、Threshold、Reason 等資訊。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
此為 Undocumented Trace Flags: DBCC TRACEON(8666)&lt;br /&gt;
適用版本: SQL Server 2008 以上的環境&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHBjsyxzKW5tpGeDaP6lV2NsOaX6L9j4gl5SW8EcZ8Mdnbgi-zJm6ujfOkf9SyhvcCcnShr1hA9BQekU5GLBnI2ASAEmCUlF58mBF6n6ANbPnaLAk9judFGBfl4elLIUPJoZlQoTyK6iw/s1600/05_SELECT_Properties_Internal+Debugging+Information.png" imageanchor="1"&gt;&lt;img border="0" height="292" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHBjsyxzKW5tpGeDaP6lV2NsOaX6L9j4gl5SW8EcZ8Mdnbgi-zJm6ujfOkf9SyhvcCcnShr1hA9BQekU5GLBnI2ASAEmCUlF58mBF6n6ANbPnaLAk9judFGBfl4elLIUPJoZlQoTyK6iw/s640/05_SELECT_Properties_Internal+Debugging+Information.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
檢視 ModTrackingInfo 元素&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;StatName: _WA_Sys_00000003_014935CB&lt;/li&gt;
&lt;li&gt;ColName: ContactName&lt;/li&gt;
&lt;li&gt;ModCtr: 91&lt;/li&gt;
&lt;li&gt;RowCount: 91&lt;/li&gt;
&lt;li&gt;Threshold: 500&lt;/li&gt;
&lt;li&gt;Reason: small table&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXKoJkbp7Qqxt5u4TW7s_WuZfwMGptPRaUWu8NmqTc4UCk-lYOk9BYwXsdQpbUmym-UawojA4NZrYADBJ1O_IPxaqZJDbmUFB9O5InNh8qFzjA3WHqUm3swSQ3E0Q8EAgfERpL5gh3hYo/s1600/06_ModTractkingInfo.png" imageanchor="1"&gt;&lt;img border="0" height="439" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXKoJkbp7Qqxt5u4TW7s_WuZfwMGptPRaUWu8NmqTc4UCk-lYOk9BYwXsdQpbUmym-UawojA4NZrYADBJ1O_IPxaqZJDbmUFB9O5InNh8qFzjA3WHqUm3swSQ3E0Q8EAgfERpL5gh3hYo/s640/06_ModTractkingInfo.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhc_nqQ5xMES1iOegXxVUpVkKkNiE7GJNhTO7u-oF261YflJcUmJZA_2d5WSZEk_6Gd2t59EJBvzPBL_1yXEJux-5pXGCjuIGGmtYGOJIe5HGHXtR8fxSBiC-GKbHikBrISnGTkDhruP4g/s1600/07_Execution_Plan_Statisitcs.png" imageanchor="1"&gt;&lt;img border="0" height="426" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhc_nqQ5xMES1iOegXxVUpVkKkNiE7GJNhTO7u-oF261YflJcUmJZA_2d5WSZEk_6Gd2t59EJBvzPBL_1yXEJux-5pXGCjuIGGmtYGOJIe5HGHXtR8fxSBiC-GKbHikBrISnGTkDhruP4g/s640/07_Execution_Plan_Statisitcs.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Find out Statistics used to Execution Plan from Plan Cache - DBCC TRACEON(8666),&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;由 Plan Cache 找出 執行計畫 所使用的 統計值 - - DBCC TRACEON(8666)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
本文 以下介紹 2 種用法:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;(1) 由&amp;nbsp;&lt;span style="color: blue;"&gt;Plan Cache (Memory)&lt;/span&gt;&lt;span style="color: purple;"&gt;&amp;nbsp;&lt;/span&gt;取得 Execution Plan 所使用的 Statistics -&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;啟用 TRACEON(8666) ，並執行 sys.dm_exec_query_plan&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
用法：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;啟用 DBCC TRACEON(8666) 後，可以使用 sys.dm_exec_query_plan 由 Plan Cache ，取得 Query Optimizer 在 Execution Plan 所使用的 Statisitics。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
功能：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;將 內部偵錯用訊息 存放於 Execution Plan 內，這包含了 Statistics 細節資訊。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
若沒有啟用 DBCC TRACEON(8666) ，則 sys.dm_exec_query_plan 顯示為 NULL，沒有資料。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;(2) 由 Include &lt;span style="color: blue;"&gt;Actual Execution Plan&lt;/span&gt; / Display &lt;span style="color: blue;"&gt;Estimated Execution Plan &lt;/span&gt;，取得 Execution Plan 所使用的 Statistics&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;- 啟用 TRACEON(8666)&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
用法：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;若搭配指定的 SQL Query，使用 Include Actual Execution Plan / Display Estimated Execution Plan，可以取得 Query Optimizer 在 Execution Plan 所使用的 Statistics。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
功能：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;將 內部偵錯用訊息 存放於 Execution Plan 內，這包含了 Statistics 細節資訊。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;(1) 由&amp;nbsp;&lt;span style="color: blue;"&gt;Plan Cache (Memory)&lt;/span&gt;&lt;span style="color: purple;"&gt;&amp;nbsp;&lt;/span&gt;取得 Execution Plan 所使用的 Statistics&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;啟用 TRACEON(8666) ，並執行 sys.dm_exec_query_plan&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;用法： 啟用 DBCC TRACEON(8666) 後，可以使用 sys.dm_exec_query_plan 由 Plan Cache ，取得 Query Optimizer 在 Execution Plan 所使用的 Statisitics。&lt;/li&gt;
&lt;li&gt;功能： 將 內部偵錯用訊息 存放於 Execution Plan 內，這包含了 Statistics 細節資訊。&lt;/li&gt;
&lt;li&gt;若沒有啟用 DBCC TRACEON(8666) ，sys.dm_exec_query_plan 的 [Statistics] 顯示 NULL，沒有資料。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
01. 使用 dm_db_stats_properties: 傳回 資料表 的所有 Statistics 屬性&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Table: Customers, Orders&lt;/li&gt;
&lt;li&gt;已經存在 15 個 Statistics&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;01_dm_db_stats_properties Returns properties of statistics for the specified database object&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5pANFHyjQGIIAgXABrFYaNI6VK_NLYkvJe2Zp8PSMEQyi9iAoNjCSKIBVQBLualeCQqL8jsIEXetFkPbAZEKsfpE2PnOM4U4tYCI-yBss0WZyUcSsrnzs-mzqiU7N4BJGygY1UoqCriE/s1600/01_dm_db_stats_properties+Returns+properties+of+statistics+for+the+specified+database+object.png" imageanchor="1"&gt;&lt;img border="0" height="321" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5pANFHyjQGIIAgXABrFYaNI6VK_NLYkvJe2Zp8PSMEQyi9iAoNjCSKIBVQBLualeCQqL8jsIEXetFkPbAZEKsfpE2PnOM4U4tYCI-yBss0WZyUcSsrnzs-mzqiU7N4BJGygY1UoqCriE/s640/01_dm_db_stats_properties+Returns+properties+of+statistics+for+the+specified+database+object.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 執行 SQL Query。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;僅查詢單一資料表。&lt;/li&gt;
&lt;li&gt;DBCC FREEPROCCACHE: 清除 Plan Cache，此為非必要，在本範例中，也僅是用於重置環境參數。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;02_Removes plan cache and Query Table with Auto Create Statistics&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi65p0LDVOCoSqBop33cQS0T4opd0gBbGYK-2aA_JWdEHG6NitFlrB-SqotlHvWk4ro2Q4ec6HIMJdDA3BeMDz9AF0jdEU9fdHHrj6PI1XIwu3R-tMS6DJbJX6LMivXvzL-82GD87JLEZ0/s1600/02_Removes+plan+cache+and+Query+Table+with+Auto+Create+Statistics.png" imageanchor="1"&gt;&lt;img border="0" height="344" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi65p0LDVOCoSqBop33cQS0T4opd0gBbGYK-2aA_JWdEHG6NitFlrB-SqotlHvWk4ro2Q4ec6HIMJdDA3BeMDz9AF0jdEU9fdHHrj6PI1XIwu3R-tMS6DJbJX6LMivXvzL-82GD87JLEZ0/s640/02_Removes+plan+cache+and+Query+Table+with+Auto+Create+Statistics.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 啟用 TRACEON(8666) ，並執行 sys.dm_exec_query_plan&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;用法： 啟用 DBCC TRACEON(8666) 後，可以使用 sys.dm_exec_query_plan 由 Plan Cache ，取得 Query Optimizer 在 Execution Plan 所使用的 Statisitics。&lt;/li&gt;
&lt;li&gt;功能： 將 內部偵錯用訊息 存放於 Execution Plan 內，這包含了 Statistics 細節資訊。&lt;/li&gt;
&lt;li&gt;若沒有啟用 DBCC TRACEON(8666) ，sys.dm_exec_query_plan 的 [Statistics] 顯示 NULL，沒有資料。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
SQL Script 說明&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;啟用 DBCC TRACEON(8666)&lt;/li&gt;
&lt;li&gt;執行 sys.dm_exec_query_plan，取得 Execution Plan&amp;nbsp; 所使用的 Statistics&lt;/li&gt;
&lt;li&gt;關閉 DBCC TRACEOFF(8666)&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: sql"&gt;-- DBCC TRACEON(8666) -- Find out Statistics used to Execution Plan from Plan Cache.
DBCC TRACEON(8666)

SELECT TOP 100 st.text [TSQL], DB_NAME(st.dbid) [DB], 
 qs.last_elapsed_time/1000000.0 [LastElapsedTime(sec)],
 qs.last_worker_time/1000000.0 [LastCPUTime(sec)],
 qs.last_logical_reads LastLogicalReads,
 qs.last_physical_reads LastPhysicalRead,
 qs.last_logical_writes LastlogicalWrites,
 qs.last_rows LastRows,
 cp.usecounts [ExecutionCount], cp.size_in_bytes/1024.0 [PlanSize(KB)],
 cp.cacheobjtype [CacheObject], cp.objtype [ObjType], qs.plan_generation_num [PlanRecompile],
 qp.query_plan.query('declare namespace ns="http://schemas.microsoft.com/sqlserver/2004/07/showplan";
 (/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/ns:QueryPlan/ns:ParameterList/ns:ColumnReference[@Column])') [ParameterList],
 qp.query_plan.query('declare namespace ns="http://schemas.microsoft.com/sqlserver/2004/07/showplan";
 (/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/ns:QueryPlan/ns:InternalInfo/ns:EnvColl/ns:Recompile)') [Statistics], 
 qp.query_plan [QueryPlan], cp.plan_handle, qs.last_execution_time, qs.creation_time
FROM sys.dm_exec_cached_plans cp INNER JOIN sys.dm_exec_query_stats qs
 ON cp.plan_handle = qs.plan_handle
 CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) st
 CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) qp
WHERE st.dbid = DB_ID('Northwind')
-- CHARINDEX ('Products', st.text) &amp;gt;0
-- st.text LIKE '%xxx%'
ORDER BY qs.last_execution_time DESC;

DBCC TRACEOFF(8666)
GO
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;03_ DBCC TRACEON(8666) -- Find out Statistics used to Execution Plan from Plan Cache.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhr4eqvFnW0mEdZIVhpdd6LEctRK_gPL5iYPekpowvHm6_vgNUkuIwsROBO3jjZBY6vJAy5AHbqFOaoL70RbkEfk1GGHhWknXK9JVB2MpaF0DB1RtJ04xBgiWpCIzCsHGiFDtH8KHsrsI0/s1600/03_+DBCC+TRACEON%25288666%2529+--+Find+out+Statistics+used+to+Execution+Plan+from+Plan+Cache..png" imageanchor="1"&gt;&lt;img border="0" height="268" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhr4eqvFnW0mEdZIVhpdd6LEctRK_gPL5iYPekpowvHm6_vgNUkuIwsROBO3jjZBY6vJAy5AHbqFOaoL70RbkEfk1GGHhWknXK9JVB2MpaF0DB1RtJ04xBgiWpCIzCsHGiFDtH8KHsrsI0/s640/03_+DBCC+TRACEON%25288666%2529+--+Find+out+Statistics+used+to+Execution+Plan+from+Plan+Cache..png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
04. 檢視 回傳的結果集。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;QueryPlan: 存放 Execution Plan。&lt;/li&gt;
&lt;li&gt;Statistics: 存放 XML 格式的 Statistics。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;04_Get_Statistics_XML&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiemd8nh1YIn2CEkfQh8DuwI_KIujlahlqYUxXHNKLM5xJzvwmD1q0UKAPZWWmjHhL5whG_nnwMX_C2_ui1eu2399J9O7viOxmDsLore6mIuP1J2yj51xJ2uaO7bsLi26vpCBvfDtg8GB0/s1600/04_Get_Statistics_XML.png" imageanchor="1"&gt;&lt;img border="0" height="56" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiemd8nh1YIn2CEkfQh8DuwI_KIujlahlqYUxXHNKLM5xJzvwmD1q0UKAPZWWmjHhL5whG_nnwMX_C2_ui1eu2399J9O7viOxmDsLore6mIuP1J2yj51xJ2uaO7bsLi26vpCBvfDtg8GB0/s640/04_Get_Statistics_XML.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
05. 檢視 QueryPlan 內的 Execution Plan&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;點選左邊的 SELECT operator，滑鼠右鍵，選擇 Properties。&lt;/li&gt;
&lt;li&gt;在右邊 Properties 窗格，展開 &lt;span style="color: blue;"&gt;Internal Debugging Information&lt;/span&gt;。&lt;/li&gt;
&lt;li&gt;展開 與 觀察 &lt;span style="color: blue;"&gt;Recompile &lt;/span&gt;與 &lt;span style="color: blue;"&gt;ModTrackingInfo&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;05_SELECT_Properties_Internal Debugging Information&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNn9tmhaKsrDHlgEu2XBGa9yLk2ujgwyezyjRRTB1OdKM1-tf8j6tO0PkOkqzpX_lpe25c4IBVJltulG3meUaXlIhrHXICyVimcNAtmow089mOq_X4KMqe1YpnTDKd3zmJQg26pVen3aQ/s1600/05_SELECT_Properties_Internal+Debugging+Information.png" imageanchor="1"&gt;&lt;img border="0" height="292" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNn9tmhaKsrDHlgEu2XBGa9yLk2ujgwyezyjRRTB1OdKM1-tf8j6tO0PkOkqzpX_lpe25c4IBVJltulG3meUaXlIhrHXICyVimcNAtmow089mOq_X4KMqe1YpnTDKd3zmJQg26pVen3aQ/s640/05_SELECT_Properties_Internal+Debugging+Information.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
06. 在 &lt;span style="color: blue;"&gt;ModTractkingInfo&lt;/span&gt;，展開 顯示 更多資訊關於 Statistics 資訊。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;06_ModTrackingInfo&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjccU6t6bSdtJGdj5RciwWtw-rJS95TZ1m_c_eRcK7y5w7LHBXWPGyQy-hi9fBHnzDFEMzyzQH5F3SaWNiUShFtR2c4pvBDG4rwx6kYtLWLwVnFH6F57gTDQaD7jNIjG7Tr3xTqoGrb5Ok/s1600/06_ModTractkingInfo.png" imageanchor="1"&gt;&lt;img border="0" height="440" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjccU6t6bSdtJGdj5RciwWtw-rJS95TZ1m_c_eRcK7y5w7LHBXWPGyQy-hi9fBHnzDFEMzyzQH5F3SaWNiUShFtR2c4pvBDG4rwx6kYtLWLwVnFH6F57gTDQaD7jNIjG7Tr3xTqoGrb5Ok/s640/06_ModTractkingInfo.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
07. 檢視 由 Plan Cache 取得的 Statistics 資訊&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;以 XML 格式呈現的 Statistics。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;07_Execution_Plan_Statistics&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOrb22eV9CFsfNBsYQMoarx8qP9T0FgeFmwgPDpUEHYO8GVJK3J8kM9iGBT93fZDJemIqbOVF73OOuRzYqlFBIYMtzNEdpWtQZBUJ_Rvgxn-YeooyzwNxy-oMD8DBQ14jD2Tx-GedW_io/s1600/07_Execution_Plan_Statisitcs.png" imageanchor="1"&gt;&lt;img border="0" height="426" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOrb22eV9CFsfNBsYQMoarx8qP9T0FgeFmwgPDpUEHYO8GVJK3J8kM9iGBT93fZDJemIqbOVF73OOuRzYqlFBIYMtzNEdpWtQZBUJ_Rvgxn-YeooyzwNxy-oMD8DBQ14jD2Tx-GedW_io/s640/07_Execution_Plan_Statisitcs.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
08. 檢視 &lt;span style="color: blue;"&gt;ModTrackingInfo &lt;/span&gt;元素&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;StatName:&amp;nbsp;_WA_Sys_00000003_014935CB&lt;/li&gt;
&lt;li&gt;ColName:&amp;nbsp;ContactName&lt;/li&gt;
&lt;li&gt;ModCtr: 91&lt;/li&gt;
&lt;li&gt;RowCount: 91&lt;/li&gt;
&lt;li&gt;Threshold: 500&lt;/li&gt;
&lt;li&gt;Reason:&amp;nbsp;small table&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;08_Statistics_ModTrackingInfo&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcrFJI3QVVcKreRMCTcOQ29bqUUhxgolFoOBJPk-2VQNmZmuZEM5YCp8wjhHHeycd74XlUGH7RRqq5NuJ6E8cx55grBzQE50IQbOuQ1GG5ZuzvyyKxLVaKVxTxMLwKJosoxoVfEj9gIvM/s1600/08_Statistics_ModTrackingInfo.png" imageanchor="1"&gt;&lt;img border="0" height="536" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcrFJI3QVVcKreRMCTcOQ29bqUUhxgolFoOBJPk-2VQNmZmuZEM5YCp8wjhHHeycd74XlUGH7RRqq5NuJ6E8cx55grBzQE50IQbOuQ1GG5ZuzvyyKxLVaKVxTxMLwKJosoxoVfEj9gIvM/s640/08_Statistics_ModTrackingInfo.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
09. 以 XML 格式 來檢視 Execution Plan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;InternalInfo 元素&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;09_XML&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhChMV8lA5iIOHPJ081YJaVfegyXZ4nNeqlAMgaF_am1maeWv47Q85F3EpOWLZ9hRhp7ONVpyN9SLnDdNc0VhxEIbCA16c79I3rcwMwW-6FrHdXrxdDYFWHKrP5yV46B99OcWyrvpGBD1w/s1600/09_XML.png" imageanchor="1"&gt;&lt;img border="0" height="376" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhChMV8lA5iIOHPJ081YJaVfegyXZ4nNeqlAMgaF_am1maeWv47Q85F3EpOWLZ9hRhp7ONVpyN9SLnDdNc0VhxEIbCA16c79I3rcwMwW-6FrHdXrxdDYFWHKrP5yV46B99OcWyrvpGBD1w/s640/09_XML.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
10. 以 XML 格式 來檢視 Execution Plan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Recompile 元素&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;10_XML&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicOK4iQns5bm0dh-EY7SOQhIcJSMzyZc50Kn9l2iSPUg_dzBw4-uZaplfvTk2AXHc42eqs7dJ25eoh1VUR9VyEMwxk1B5Djmw7WdxVXm7oGkq_2LmFBBdnM_O2uz867dHttUoJTCN6UGM/s1600/10_XML.png" imageanchor="1"&gt;&lt;img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicOK4iQns5bm0dh-EY7SOQhIcJSMzyZc50Kn9l2iSPUg_dzBw4-uZaplfvTk2AXHc42eqs7dJ25eoh1VUR9VyEMwxk1B5Djmw7WdxVXm7oGkq_2LmFBBdnM_O2uz867dHttUoJTCN6UGM/s640/10_XML.png" width="626" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
11. 以 XML 格式 來檢視 Execution Plan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;ModTrackingInfo 元素&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;11_XML_ModTrackingInfo&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBq2q3k2csRkBHfij1lT_BSCObIDutGuekztzQGMAHtd0zkLnXV9E2zyrSe7nDD2JAb1oy1I_ewhya3f86Y5Jfu64AKhXOnhliMEBdQ3x4VL1FCSEl0SuygUplPSUyjNhRAWv_z9m6jRM/s1600/11_XML_ModTrackingInfo.png" imageanchor="1"&gt;&lt;img border="0" height="416" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBq2q3k2csRkBHfij1lT_BSCObIDutGuekztzQGMAHtd0zkLnXV9E2zyrSe7nDD2JAb1oy1I_ewhya3f86Y5Jfu64AKhXOnhliMEBdQ3x4VL1FCSEl0SuygUplPSUyjNhRAWv_z9m6jRM/s640/11_XML_ModTrackingInfo.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;(2) 由 Include&amp;nbsp;&lt;/span&gt;&lt;span style="color: blue; font-size: large;"&gt;Actual Execution Plan&lt;/span&gt;&lt;span style="font-size: large;"&gt;&amp;nbsp;/ Display&amp;nbsp;&lt;/span&gt;&lt;span style="color: blue; font-size: large;"&gt;Estimated Execution Plan&amp;nbsp;&lt;/span&gt;&lt;span style="font-size: large;"&gt;，取得 Execution Plan 所使用的 Statistics&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;-- 啟用 TRACEON(8666)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
先前介紹的是由 Plan Cache (Memory) 取得 Execution Plan 所使用的 Statistics。&lt;br /&gt;
&lt;br /&gt;
以下方式，則是應用於 Include Actual Execution Plan / Display Estimated Execution Plan ，取得 在 Execution Plan 所使用的 Statistics。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
DBCC TRACEON(8666) -- Find out Statistics used to Execution Plan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;用法： 若搭配指定的 SQL Query，使用 &lt;span style="color: blue;"&gt;Include Actual Execution Plan / Display Estimated Execution Plan&lt;/span&gt;，可以取得 Query Optimizer 在 Execution Plan 所使用的 Statistics。&lt;/li&gt;
&lt;li&gt;功能： 將 內部偵錯用訊息 存放於 Execution Plan 內，這包含了 Statistics 細節資訊。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
01. 執行以下 SQL Query&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;啟用 DBCC TRACEON(8666)&lt;/li&gt;
&lt;li&gt;使用&amp;nbsp;&lt;span style="color: blue;"&gt;Include Actual Execution Plan / Display Estimated Execution Plan&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;執行 SQL Query ，僅查詢 單一 資料表&lt;/li&gt;
&lt;li&gt;關閉 DBCC TRACEOFF(8666)&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;21_Actual_Execution_Plan_DBCC TRACEON(8666)&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkbkTq2qvM-n5g92QBfysgLHeOghudAIdXbMXj8TAHfgM5tM8qlzrDFy_3L5OAneFtJT4unnJtc5-EhwjahUHlJ1Qgdu03wtK2wsybr5Empf_le8JmcUZny5hzT_y_UTjC-V2XwbTteNs/s1600/21_Actual_Execution_Plan_DBCC+TRACEON%25288666%2529.png" imageanchor="1"&gt;&lt;img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkbkTq2qvM-n5g92QBfysgLHeOghudAIdXbMXj8TAHfgM5tM8qlzrDFy_3L5OAneFtJT4unnJtc5-EhwjahUHlJ1Qgdu03wtK2wsybr5Empf_le8JmcUZny5hzT_y_UTjC-V2XwbTteNs/s640/21_Actual_Execution_Plan_DBCC+TRACEON%25288666%2529.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 檢視 Execution Plan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;點選左邊的 SELECT operator，滑鼠右鍵，選擇 &lt;span style="color: blue;"&gt;Properties&lt;/span&gt;。&lt;/li&gt;
&lt;li&gt;在右邊 Properties 窗格，展開 &lt;span style="color: blue;"&gt;Internal Debugging Information&lt;/span&gt;。&lt;/li&gt;
&lt;li&gt;展開 與 觀察 &lt;span style="color: blue;"&gt;Recompile &lt;/span&gt;與 &lt;span style="color: blue;"&gt;ModTrackingInfo&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
可以看到 1 份 Statistics 資訊，檢視 ModTrackingInfo 元素&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;StatName: _WA_Sys_00000003_014935CB&lt;/li&gt;
&lt;li&gt;ColName: ContactName&lt;/li&gt;
&lt;li&gt;ModCtr: 91&lt;/li&gt;
&lt;li&gt;RowCount: 91&lt;/li&gt;
&lt;li&gt;Threshold: 500&lt;/li&gt;
&lt;li&gt;Reason: small table&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;22_Execution_Plan_SELECT_Properties_Internal Debugging Information&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAjo28kg6927i0R7d04xpCWyHGPxxmCXQkni6wUPe2HPmoLSk_bI-QeNSKmpWxKMp_Pm4HieNaNFT29WQ5NxySqHHVYwbC68VdVAmywAfQhfOkKHVfcPgQKWmPpFWSDGSJyI2Pk2zlEIQ/s1600/22_Execution_Plan_SELECT_Properties_Internal+Debugging+Information.png" imageanchor="1"&gt;&lt;img border="0" height="262" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAjo28kg6927i0R7d04xpCWyHGPxxmCXQkni6wUPe2HPmoLSk_bI-QeNSKmpWxKMp_Pm4HieNaNFT29WQ5NxySqHHVYwbC68VdVAmywAfQhfOkKHVfcPgQKWmPpFWSDGSJyI2Pk2zlEIQ/s640/22_Execution_Plan_SELECT_Properties_Internal+Debugging+Information.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 執行複雜 SQL Query&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;此 SQL Query，使用 Inner Join，查詢 2 張資料表，並使用 Where 條件式。&lt;/li&gt;
&lt;li&gt;觀察 &lt;span style="color: blue;"&gt;Recompile &lt;/span&gt;與 &lt;span style="color: blue;"&gt;ModTrackingInfo&lt;/span&gt;。&lt;/li&gt;
&lt;li&gt;可以看到 當時 2 張資料表上的 &lt;span style="color: purple;"&gt;全部 Statistics 資訊，約：15 個&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
在此案例 (Inner Join) 中，啟用 DBCC TRACEON(8666) 後，會取得 當時&amp;nbsp; 參與資料表上的全部 Statistics 資訊。但仍可分析像是 條件式 Where、On 等 SQL statement，得知 當時 所使用的 Statistics。&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
-- figure&amp;nbsp;31_Display all statistics&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFpEEk2G9aaBzP8YVBfZV4bNN9A2caihH5LZP9DHYiQUS0fPR6SIwVMGt-w6ZH5VAKlCoLztNylzI6Xn-AF4jWlqgwyHJGpVGll9JacGfO_LP3KD4S1fS6hKCaIHcJZhdnxdYbhlISXKc/s1600/31_Display+all+statistics.png" imageanchor="1"&gt;&lt;img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFpEEk2G9aaBzP8YVBfZV4bNN9A2caihH5LZP9DHYiQUS0fPR6SIwVMGt-w6ZH5VAKlCoLztNylzI6Xn-AF4jWlqgwyHJGpVGll9JacGfO_LP3KD4S1fS6hKCaIHcJZhdnxdYbhlISXKc/s640/31_Display+all+statistics.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
04.&amp;nbsp;以 XML 格式 來檢視 Execution Plan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;觀察 Orders&amp;nbsp; 資料表的 Statistics。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;32_XML_Orders&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikR-nshX4Z2YUitqyipJcYtqvzbtDckGf3kGGumqOQKfHkhLTuikYdsGQKOLtrWLZiA_4a_849p3Mljxmzlru1TZ3buI5bcBm5Kdi6iUuTuqkrsJs9Gz82Fsyg8WanXrvCDJBYeKTwTXk/s1600/32_XML_Orders.png" imageanchor="1"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikR-nshX4Z2YUitqyipJcYtqvzbtDckGf3kGGumqOQKfHkhLTuikYdsGQKOLtrWLZiA_4a_849p3Mljxmzlru1TZ3buI5bcBm5Kdi6iUuTuqkrsJs9Gz82Fsyg8WanXrvCDJBYeKTwTXk/s1600/32_XML_Orders.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
05. 以 XML 格式 來檢視 Execution Plan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;觀察 Orders 資料表的 Statistics。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;33_XML&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmh9lJyVcd6ZcMq5CT6PT0jCLAjanmWE2z_rhNGbtvHnVYbIu2HY3OwPh4ctUz9i7J7GQEyrSaHaPkGDrjHcbU8F5bfYpkl9tZjulnnKyHoju3arpQhlXixzqqkStDh9_ZyZv1FTodkeA/s1600/33_XML.png" imageanchor="1"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmh9lJyVcd6ZcMq5CT6PT0jCLAjanmWE2z_rhNGbtvHnVYbIu2HY3OwPh4ctUz9i7J7GQEyrSaHaPkGDrjHcbU8F5bfYpkl9tZjulnnKyHoju3arpQhlXixzqqkStDh9_ZyZv1FTodkeA/s1600/33_XML.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
06. 以 XML 格式 來檢視 Execution Plan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;觀察 Customers 資料表的 Statistics。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;34_XML_Customers&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWqDUg17UkgBPSK-ctLXbnSbab_i_F8yGQsbOuz7d3dsZJ-AGu0vr-gUMUiYr1KMlpz2tEGEPPH1cruDiCzEYoKJzDZd5G59iFM28Jx1VHW9AIJgx0stBcDVklOEm-wyKfQjVKt1lQ7Lo/s1600/34_XML_Customers.png" imageanchor="1"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWqDUg17UkgBPSK-ctLXbnSbab_i_F8yGQsbOuz7d3dsZJ-AGu0vr-gUMUiYr1KMlpz2tEGEPPH1cruDiCzEYoKJzDZd5G59iFM28Jx1VHW9AIJgx0stBcDVklOEm-wyKfQjVKt1lQ7Lo/s1600/34_XML_Customers.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Sample Code&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
20181029_Find out Statistics_TRACEON_8666&lt;br /&gt;
&lt;a href="https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing"&gt;https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Reference&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Use Autostat (AUTO_UPDATE_STATISTICS), 認識 自動更新統計資料 (1)&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/10/statistics-use-autostat.html"&gt;http://sharedderrick.blogspot.com/2018/10/statistics-use-autostat.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Use Autostat (AUTO_UPDATE_STATISTICS), 認識 自動更新統計資料 (2)&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/10/use-autostat-autoupdatestatistics-2.html"&gt;http://sharedderrick.blogspot.com/2018/10/use-autostat-autoupdatestatistics-2.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Find out Statistics used to Execution Plan in SQL Server 2017, 找出 執行計畫 所使用的 統計值&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/10/find-out-statistics-used-to-execution.html"&gt;http://sharedderrick.blogspot.com/2018/10/find-out-statistics-used-to-execution.html&lt;/a&gt;</description><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHBjsyxzKW5tpGeDaP6lV2NsOaX6L9j4gl5SW8EcZ8Mdnbgi-zJm6ujfOkf9SyhvcCcnShr1hA9BQekU5GLBnI2ASAEmCUlF58mBF6n6ANbPnaLAk9judFGBfl4elLIUPJoZlQoTyK6iw/s72-c/05_SELECT_Properties_Internal+Debugging+Information.png" width="72"/><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><title>Find out Statistics used to Execution Plan in SQL Server 2017, 找出 執行計畫 所使用的 統計值</title><link>http://sharedderrick.blogspot.com/2018/10/find-out-statistics-used-to-execution.html</link><category>Performance Tuning</category><category>SQL Server</category><author>noreply@blogger.com (DerrickLaLa)</author><pubDate>Fri, 19 Oct 2018 22:55:00 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1420955872914622499.post-5564530617037388787</guid><description>&lt;br /&gt;
SQL Server&amp;nbsp;&lt;span style="color: blue;"&gt;&lt;b&gt;2017&lt;/b&gt;&lt;/span&gt;&amp;nbsp;強化 Execution Plan，增加 [&lt;b&gt;&lt;span style="color: blue;"&gt;OptimizerStatsUsage&lt;/span&gt;&lt;/b&gt;] 屬性，可提供 Query Optimizer 在此 Execution Plan 所使用的 Statistics。&lt;br /&gt;
&lt;br /&gt;
無論是 Include Actual Execution Plan / Display Estimated Execution Plan，都可以使用 [OptimizerStatsUsage] 屬性。&lt;br /&gt;
&lt;br /&gt;
經過測試: SQL Server 2017 版本，並且 COMPATIBILITY_LEVEL = 120 以上適用。&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_VB1riRk07sAqlfX7to9aJDQs29X0Wf60hYYErM1UUVY-U5M0UT-jKBWTGwFPD8kF2bDyaMfO5o0oF3_OPdlQzdcSZOMDNWB_JLkX5d_hUeDOCNrid0R6fRKI15-zvkyFI2-ruxrPj1Y/s1600/12_SELECT_Properties_OptimizerStatsUsage.png" imageanchor="1"&gt;&lt;img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_VB1riRk07sAqlfX7to9aJDQs29X0Wf60hYYErM1UUVY-U5M0UT-jKBWTGwFPD8kF2bDyaMfO5o0oF3_OPdlQzdcSZOMDNWB_JLkX5d_hUeDOCNrid0R6fRKI15-zvkyFI2-ruxrPj1Y/s640/12_SELECT_Properties_OptimizerStatsUsage.png" width="499" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Find out Statistics used to Execution Plan in SQL Server 2017&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;找出 Execution Plan (執行計畫&lt;/span&gt;&lt;span style="color: blue; font-size: x-large;"&gt;) 所使用的 Statistics (統計值)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
SQL Server &lt;span style="color: blue;"&gt;&lt;b&gt;2017&lt;/b&gt;&lt;/span&gt; 強化 Execution Plan，增加 [&lt;b&gt;&lt;span style="color: blue;"&gt;OptimizerStatsUsage&lt;/span&gt;&lt;/b&gt;] 屬性，可提供 Query Optimizer 在此 Execution Plan 所使用的 Statistics。&lt;br /&gt;
&lt;br /&gt;
無論是 Include Actual Execution Plan / Display Estimated Execution Plan，都可以使用 [OptimizerStatsUsage] 屬性。&lt;br /&gt;
&lt;br /&gt;
初步測試: SQL Server 2017 版本，並且 COMPATIBILITY_LEVEL = 120 以上適用。SQL Server 2014 (x.12)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
01.&amp;nbsp;使用 dm_db_stats_properties: 傳回 資料表 的所有 Statistics 屬性&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Table: Customers,&amp;nbsp;Orders&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;01_dm_db_stats_properties_Customers_Orders&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYCX3wlcQwdtnFS86ePuicCMmyll0sr089mLngAFScEF6yw8UPiVihecN5LZuxOPoxZPBqEz4BRFnMjdfFDNjSpdN3aUd3JfHZqAiy0qpeXxxhG5GvDWGHd-BxDW0IJadPucuxUMscAVY/s1600/01_dm_db_stats_properties_Customers_Orders.png" imageanchor="1"&gt;&lt;img border="0" height="308" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYCX3wlcQwdtnFS86ePuicCMmyll0sr089mLngAFScEF6yw8UPiVihecN5LZuxOPoxZPBqEz4BRFnMjdfFDNjSpdN3aUd3JfHZqAiy0qpeXxxhG5GvDWGHd-BxDW0IJadPucuxUMscAVY/s640/01_dm_db_stats_properties_Customers_Orders.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 執行 SQL Query&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;僅查詢單一資料表。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;無論是 Include &lt;span style="color: blue;"&gt;Actual Execution Plan &lt;/span&gt;/ Display &lt;span style="color: blue;"&gt;Estimated Execution Plan&lt;/span&gt;，都可以使用 [OptimizerStatsUsage] 屬性。&lt;/li&gt;
&lt;li&gt;點選 左邊 最後一個 SELECT Operator，滑鼠 右鍵，選擇 Properties。&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;自動產生 Statistics。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;依據預設值，有啟用資料庫選項：AUTO_CREATE_STATISTICS。&lt;/li&gt;
&lt;li&gt;WHERE 條件式使用 Column: ContactName，Query Optimizer 將自動為其建立 Statistics。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;11_SQL_Server 2017_SELECT&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRFG17hY8LQopcDvzRPXoGizZ06q2IKXoVAbQ9uFvUNcJaSn5oYLftGWLD8ZAWDJgjNIFet1XKppe6v9M7Ae7uyJOmV9Y5pdVofewTtZtj8kU5rv2FfyjEFx_ro3GIPlTeCEjERxeLQk4/s1600/11_SQL_Server+2017_SELECT.png" imageanchor="1"&gt;&lt;img border="0" height="234" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRFG17hY8LQopcDvzRPXoGizZ06q2IKXoVAbQ9uFvUNcJaSn5oYLftGWLD8ZAWDJgjNIFet1XKppe6v9M7Ae7uyJOmV9Y5pdVofewTtZtj8kU5rv2FfyjEFx_ro3GIPlTeCEjERxeLQk4/s640/11_SQL_Server+2017_SELECT.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 在 Properties 視窗，可以看到&amp;nbsp;[&lt;span style="color: blue;"&gt;&lt;b&gt;OptimizerStatsUsage&lt;/b&gt;&lt;/span&gt;] 區塊，使用到 1 個 Statistics，包含以下資訊：&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Database: [Northwind]&lt;/li&gt;
&lt;li&gt;LastUpdate: 2018-10-19T21:01:05.14&lt;/li&gt;
&lt;li&gt;ModificationCount: 0&lt;/li&gt;
&lt;li&gt;SamplingPercent: 100&lt;/li&gt;
&lt;li&gt;Schema: dbo&lt;/li&gt;
&lt;li&gt;Statistics: _WA_Sys_00000003_014935CB&lt;/li&gt;
&lt;li&gt;Table: [Customers]&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;12_SELECT_Properties_OptimizerStatsUsage&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0ezoa8OnouIO-SfcZMmWguFcqyPc-ds5YjhNv0gbAN2Mqwa0eBidLyogi_qAn1LFDuGwaGTXMaEA-Z063v-YbH_vsNLpln04cAWl16CWJLz8KRfVtGcJ_RYMCkjM-05ldt9YXRD2jIe4/s1600/12_SELECT_Properties_OptimizerStatsUsage.png" imageanchor="1"&gt;&lt;img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0ezoa8OnouIO-SfcZMmWguFcqyPc-ds5YjhNv0gbAN2Mqwa0eBidLyogi_qAn1LFDuGwaGTXMaEA-Z063v-YbH_vsNLpln04cAWl16CWJLz8KRfVtGcJ_RYMCkjM-05ldt9YXRD2jIe4/s640/12_SELECT_Properties_OptimizerStatsUsage.png" width="498" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
04. 檢視 Show Execution Plan XML&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;觀察&amp;nbsp;OptimizerStatsUsage&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;13_Show_Execution_Plan_XML&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIhPnFe3U1OIkTxZB9Vj6Z8-Uaj73o4r0PtmwWshgfymK2KaKEtsCunXomihcYsE3IzvPT_eaX9KQPOLNE31wxndVtFVgZ23YrAY3UpaLyPujCJEmOslVNTPGTa4cCu2l2DEIgLVen5jc/s1600/13_Show_Execution_Plan_XML.png" imageanchor="1"&gt;&lt;img border="0" height="232" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIhPnFe3U1OIkTxZB9Vj6Z8-Uaj73o4r0PtmwWshgfymK2KaKEtsCunXomihcYsE3IzvPT_eaX9KQPOLNE31wxndVtFVgZ23YrAY3UpaLyPujCJEmOslVNTPGTa4cCu2l2DEIgLVen5jc/s640/13_Show_Execution_Plan_XML.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
05. 執行 SQL Query&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Table Join 2 個&lt;/li&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;無論是 Include&amp;nbsp;&lt;span style="color: blue;"&gt;Actual Execution Plan&amp;nbsp;&lt;/span&gt;/ Display&amp;nbsp;&lt;span style="color: blue;"&gt;Estimated Execution Plan&lt;/span&gt;，都可以使用 [OptimizerStatsUsage] 屬性。&lt;/li&gt;
&lt;li&gt;點選 左邊 最後一個 SELECT Operator，滑鼠 右鍵，選擇 Properties。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
-- figure&amp;nbsp;14_SQL_Server 2017_SELECT&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaU1gZyHW_I2Sl8mp3lKYflSPVezfSUTFQl1OikOkbHQkJjAWwUEE1qG74NmaO248KXflvKPzgVd3Od2NQnvkeN-I8vbMQqN0-0cg-WBd4j-jsXrUAoCCcKh78MIVYKHQpF8BtYHIeWTA/s1600/14_SQL_Server+2017_SELECT.png" imageanchor="1"&gt;&lt;img border="0" height="334" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaU1gZyHW_I2Sl8mp3lKYflSPVezfSUTFQl1OikOkbHQkJjAWwUEE1qG74NmaO248KXflvKPzgVd3Od2NQnvkeN-I8vbMQqN0-0cg-WBd4j-jsXrUAoCCcKh78MIVYKHQpF8BtYHIeWTA/s640/14_SQL_Server+2017_SELECT.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
06. 在 Properties 視窗，可以看到&amp;nbsp;[&lt;span style="color: blue;"&gt;&lt;b&gt;OptimizerStatsUsage&lt;/b&gt;&lt;/span&gt;] 區塊，使用到 3 個 Statistics，包含以下資訊：&lt;br /&gt;
&lt;br /&gt;
[1]&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Database: [Northwind]&lt;/li&gt;
&lt;li&gt;LastUpdate: 2018-10-19T21:01:05.14&lt;/li&gt;
&lt;li&gt;ModificationCount: 0&lt;/li&gt;
&lt;li&gt;SamplingPercent: 100&lt;/li&gt;
&lt;li&gt;Schema: dbo&lt;/li&gt;
&lt;li&gt;Statistics: _WA_Sys_00000003_014935CB&lt;/li&gt;
&lt;li&gt;Table: [Customers]&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
[2]&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Database: [Northwind]&lt;/li&gt;
&lt;li&gt;LastUpdate: 2008-09-13T13:06:45.8&lt;/li&gt;
&lt;li&gt;ModificationCount: 0&lt;/li&gt;
&lt;li&gt;SamplingPercent: 100&lt;/li&gt;
&lt;li&gt;Schema: dbo&lt;/li&gt;
&lt;li&gt;Statistics: [CustomerID]&lt;/li&gt;
&lt;li&gt;Table: [Orders]&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
[3]&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Database: [Northwind]&lt;/li&gt;
&lt;li&gt;LastUpdate: 2008-09-13T13:06:45.77&lt;/li&gt;
&lt;li&gt;ModificationCount: 0&lt;/li&gt;
&lt;li&gt;SamplingPercent: 100&lt;/li&gt;
&lt;li&gt;Schema: dbo&lt;/li&gt;
&lt;li&gt;Statistics: [PK_Customers]&lt;/li&gt;
&lt;li&gt;Table: [Customers]&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;15_SELECT_Properties_OptimizerStatsUsage&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDLzkc9VNNkeR6vHFMVqb3ShWUMhSHo22fWIKY0DQvs5xiUlcM9jDpg0zDZb2amoh2J-kZbcjhxDrAWn4EndxEvnCa1TxOuJiJvj7OTxO3yPWE-X42byDZ1T4prHr0hlcGTK6wlA1CQE0/s1600/15_SELECT_Properties_OptimizerStatsUsage.png" imageanchor="1"&gt;&lt;img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDLzkc9VNNkeR6vHFMVqb3ShWUMhSHo22fWIKY0DQvs5xiUlcM9jDpg0zDZb2amoh2J-kZbcjhxDrAWn4EndxEvnCa1TxOuJiJvj7OTxO3yPWE-X42byDZ1T4prHr0hlcGTK6wlA1CQE0/s640/15_SELECT_Properties_OptimizerStatsUsage.png" width="548" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
07. 檢視 Show Execution Plan XML&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;觀察&amp;nbsp;OptimizerStatsUsage&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;16_Show_Execution_Plan_XML&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizlAUqbxPGTFMBbrcBfRn5boXmltVXq0D3kQ_o0wjHeVpJf_nXt_cHcR6I3naAW4PHh0ze9JrZUqaos39rbpVPB2SH1ijDpmW4XG_un5Bth8d77K6RAysu-2PKUqN84kKEnm13BRplCDc/s1600/16_Show_Execution_Plan_XML.png" imageanchor="1"&gt;&lt;img border="0" height="120" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizlAUqbxPGTFMBbrcBfRn5boXmltVXq0D3kQ_o0wjHeVpJf_nXt_cHcR6I3naAW4PHh0ze9JrZUqaos39rbpVPB2SH1ijDpmW4XG_un5Bth8d77K6RAysu-2PKUqN84kKEnm13BRplCDc/s640/16_Show_Execution_Plan_XML.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
08.&amp;nbsp;使用 SSMS 檢視 Index 與 Statistics&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;17_SSMS_Statistics&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgC4NnkcppMb7syEZ8-YZUPbl3BacmFGCaj2B69Ldur9gJdvkdb48ORPQDeuasQfl5sqTzupCrNuZke-d-_h-baUYoDEri9MXnlX7yVsGdh-A_H4tSksrcx2BOJziABC6dBlawPax8CHmQ/s1600/17_SSMS_Statistics.png" imageanchor="1"&gt;&lt;img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgC4NnkcppMb7syEZ8-YZUPbl3BacmFGCaj2B69Ldur9gJdvkdb48ORPQDeuasQfl5sqTzupCrNuZke-d-_h-baUYoDEri9MXnlX7yVsGdh-A_H4tSksrcx2BOJziABC6dBlawPax8CHmQ/s640/17_SSMS_Statistics.png" width="322" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Sample Code&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
20181019_Find out Statistics used to Execution Plan&lt;br /&gt;
&lt;a href="https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing"&gt;https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Reference&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Use Autostat (AUTO_UPDATE_STATISTICS), 認識 自動更新統計資料 (1)&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/10/statistics-use-autostat.html"&gt;http://sharedderrick.blogspot.com/2018/10/statistics-use-autostat.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Use Autostat (AUTO_UPDATE_STATISTICS), 認識 自動更新統計資料 (2)&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/10/use-autostat-autoupdatestatistics-2.html"&gt;http://sharedderrick.blogspot.com/2018/10/use-autostat-autoupdatestatistics-2.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</description><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_VB1riRk07sAqlfX7to9aJDQs29X0Wf60hYYErM1UUVY-U5M0UT-jKBWTGwFPD8kF2bDyaMfO5o0oF3_OPdlQzdcSZOMDNWB_JLkX5d_hUeDOCNrid0R6fRKI15-zvkyFI2-ruxrPj1Y/s72-c/12_SELECT_Properties_OptimizerStatsUsage.png" width="72"/><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><title>Use Autostat (AUTO_UPDATE_STATISTICS), 認識 自動更新統計資料 (2)</title><link>http://sharedderrick.blogspot.com/2018/10/use-autostat-autoupdatestatistics-2.html</link><category>Performance Tuning</category><category>SQL Server</category><category>效能調教</category><author>noreply@blogger.com (DerrickLaLa)</author><pubDate>Tue, 16 Oct 2018 07:21:00 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1420955872914622499.post-7310869519895199763</guid><description>&lt;br /&gt;
&lt;div&gt;
&lt;div&gt;
從 SQL Server 2016 (13.x) 開始，並且&amp;nbsp; &lt;span style="color: blue;"&gt;COMPATIBILITY_LEVEL = 130&lt;/span&gt;&amp;nbsp;(資料庫相容性層級 )， 系統採用 Dynamic auto update statistics threshold (動態 自動更新統計資料閾值)&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;使用降低、動態的統計資料更新臨界值。此臨界值會根據資料表中的資料列數目來做出調整。&amp;nbsp;&lt;/li&gt;
&lt;li&gt;這是以 &lt;span style="color: blue;"&gt;1000 乘以目前資料表基數的平方根&lt;/span&gt;來計算。&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;例如&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;如資料表包含 2 百萬個資料列，則計算結果是 &lt;span style="color: blue;"&gt;SQRT&lt;/span&gt;(1000 * 2000000) = 44721.359。&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
案例&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;資料表有 10 萬筆資料列，若要達到自動更新統計資訊的 threshold&lt;div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;&lt;ul&gt;
&lt;li&gt;需要有 10, 000 筆以上被異動。&lt;/li&gt;
&lt;li&gt;計算： SELECT SQRT (1000 * 100000) = 10000&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;在具有 100,000 行的表中，觸發更新統計信息的閾值已降至 10 %。&lt;/li&gt;
&lt;li&gt;在一個包含 1,000,000 行的表中，它只需要大約 3.2 % 的異動，即可觸發自動更新統計信息。&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
透過這項變更，大型資料表上的統計資料會經常更新。&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
不過，如果資料庫的相容性層級低於 130，便會套用 SQL Server 2014 (12.x) 臨界值。&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="color: blue; font-size: large;"&gt;追蹤旗標 2371&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;在資料庫相容性層級 &lt;span style="color: blue;"&gt;低於 130 &lt;/span&gt;之下，從 SQL Server 2008 R2 開始至 SQL Server 2014 (12.x)。或是，從 SQL Server 2016 (13.x) 至 SQL Server 2017，使用 追蹤旗標 2371 時，&amp;nbsp;&lt;/li&gt;
&lt;li&gt;SQL Server 就會使用降低、動態的統計資料更新臨界值。此臨界值會根據資料表中的資料列數目來做出調整。&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;對於較小的表格，閾值仍將是大約 20% 的百分比。&lt;/li&gt;
&lt;li&gt;當每個表超過 25,000 行時，動態規則才會啟動，並且隨著行數的增加，更改的記錄百分比變得越來越低。&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;更新 Statistics (統計值) 的 Threshold&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;table border="1" cellpadding="1" cellspacing="1"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;SQL Server 2014 (&lt;span style="color: purple;"&gt;12.x&lt;/span&gt;)&lt;/td&gt;&lt;td&gt;SQL Server 2016 (&lt;span style="color: blue;"&gt;13.x&lt;/span&gt;)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Threshold&lt;/td&gt;&lt;td&gt;資料表基數的 20% + 500&lt;/td&gt;&lt;td&gt;以 1000 乘以目前資料表基數的平方根&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Example&lt;/td&gt;&lt;td&gt;(100000 *&lt;span style="color: purple;"&gt;&amp;nbsp;0.2&lt;/span&gt;) +&amp;nbsp;&lt;span style="color: purple;"&gt;500&amp;nbsp;&lt;/span&gt;= 20,500&lt;/td&gt;&lt;td&gt;&lt;span style="color: blue;"&gt;SQRT&amp;nbsp;&lt;/span&gt;(&lt;span style="color: blue;"&gt;1000&amp;nbsp;&lt;/span&gt;* 100000) = 10,000&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
-- figure&amp;nbsp;53_Excel_Threshold&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXhiRbwfH_-QnprnIusBHSEhRSkpVwj2FeAdpdkLkSctDCkoGWZkvhyACizwPGyDkM3v-cjhdtUM_kSJ7KVumIxJduDblCaA-DX8cLn3jztJTLZCnsd0vzAe7StXsWdmZP_NK5k2nwf6I/s1600/53_Excel_Threshold.png" imageanchor="1"&gt;&lt;img border="0" height="270" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXhiRbwfH_-QnprnIusBHSEhRSkpVwj2FeAdpdkLkSctDCkoGWZkvhyACizwPGyDkM3v-cjhdtUM_kSJ7KVumIxJduDblCaA-DX8cLn3jztJTLZCnsd0vzAe7StXsWdmZP_NK5k2nwf6I/s640/53_Excel_Threshold.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;54_Threshold_Chart&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNEH-0Xo8_9-BEMwLf4FBLuVafYKzG5TFz89YWrGdKmqyLvLftIwcadVMS47hQ45qLeLuI2FRuNV0KAMSiyFr78-KCIn2eFYOIww0jBTSfZa_CR27vIZB4LgLZEzMs_NuopHZQisOWKLg/s1600/54_Threshold_Chart.png" imageanchor="1"&gt;&lt;img border="0" height="396" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNEH-0Xo8_9-BEMwLf4FBLuVafYKzG5TFz89YWrGdKmqyLvLftIwcadVMS47hQ45qLeLuI2FRuNV0KAMSiyFr78-KCIn2eFYOIww0jBTSfZa_CR27vIZB4LgLZEzMs_NuopHZQisOWKLg/s640/54_Threshold_Chart.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Statistics: Use Autostat (AUTO_UPDATE_STATISTICS ), 認識 自動更新統計資料 (2)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: white; color: #222222; font-family: &amp;quot;arial&amp;quot; , &amp;quot;tahoma&amp;quot; , &amp;quot;helvetica&amp;quot; , &amp;quot;freesans&amp;quot; , sans-serif; font-size: 13.2px;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="background-color: white; color: #222222; font-family: &amp;quot;arial&amp;quot; , &amp;quot;tahoma&amp;quot; , &amp;quot;helvetica&amp;quot; , &amp;quot;freesans&amp;quot; , sans-serif; font-size: 13.2px;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="background-color: white; color: #222222; font-family: &amp;quot;arial&amp;quot; , &amp;quot;tahoma&amp;quot; , &amp;quot;helvetica&amp;quot; , &amp;quot;freesans&amp;quot; , sans-serif; font-size: 13.2px;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="background-color: white; color: #222222; font-family: &amp;quot;arial&amp;quot; , &amp;quot;tahoma&amp;quot; , &amp;quot;helvetica&amp;quot; , &amp;quot;freesans&amp;quot; , sans-serif; font-size: 13.2px;"&gt;00. 依據預設值，資料庫屬性：Auto Create Statistics 與 Auto Update Statistics 已經啟用。&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
-- figure 51_Autostat&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXsMGPxka7VRkI1TzvK6I6MGwXpZ3dgyjEXUTHerereRrgx12qLELFJHjhzV2Y0VleZK3Ezz2RMY0BVkSE1077ddarzwsaRrN1sMaOUOG3sD2-K06XYQ5r0G1qxcI27JqULXVTXjoW6YA/s1600/51_Auto.png" imageanchor="1"&gt;&lt;img border="0" height="580" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXsMGPxka7VRkI1TzvK6I6MGwXpZ3dgyjEXUTHerereRrgx12qLELFJHjhzV2Y0VleZK3Ezz2RMY0BVkSE1077ddarzwsaRrN1sMaOUOG3sD2-K06XYQ5r0G1qxcI27JqULXVTXjoW6YA/s640/51_Auto.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
01. 檢查 COMPATIBILITY_LEVEL&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;確認 COMPATIBILITY_LEVEL = &lt;span style="color: blue;"&gt;&lt;b&gt;130&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;將 固定 自動更新統計資料閾值 變更為 &lt;span style="color: blue;"&gt;動態&lt;/span&gt; 自動更新統計資料閾值。&amp;nbsp;&lt;/li&gt;
&lt;li&gt;SQL Server 會使用降低、動態的統計資料更新臨界值。此臨界值會根據資料表中的資料列數目來做出調整。&amp;nbsp;&lt;/li&gt;
&lt;li&gt;這是以 &lt;span style="color: blue;"&gt;1000 乘以目前資料表基數的平方根&amp;nbsp;&lt;/span&gt;計算。&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;更新 Statistics 的 Threshold(臨界值)是：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;如果您的資料表包含 2 百萬個資料列，則計算結果是 SQRT(1000 * 2000000) = 44721.359。&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
透過這項變更，大型資料表上的統計資料會經常更新。&lt;br /&gt;
不過，如果資料庫的相容性層級低於 130，便會套用 SQL Server 2014 (12.x) 臨界值。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;追蹤旗標 2371&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;將 固定 自動更新統計資料閾值 變更為 &lt;span style="color: blue;"&gt;動態 自動更新統計資料閾值&lt;/span&gt;。&amp;nbsp;&lt;/li&gt;
&lt;li&gt;在資料庫相容性層級 低於 130 之下，從 SQL Server 2008 R2 開始至 SQL Server 2014 (12.x)。&lt;/li&gt;
&lt;li&gt;或是，從 SQL Server 2016 (13.x) 至 SQL Server 2017，使用追蹤旗標 2371 時，&amp;nbsp;&lt;/li&gt;
&lt;li&gt;SQL Server 就會使用降低、動態的統計資料更新臨界值。此臨界值會根據資料表中的資料列數目來做出調整。&lt;/li&gt;
&lt;li&gt;當每個表超過 25,000 行時，動態規則才會啟動，並且隨著行數的增加，更改的記錄百分比變得越來越低。&lt;/li&gt;
&lt;li&gt;例如&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;在具有 100,000 行的表中，觸發更新統計信息的閾值已降至 10%。&lt;/li&gt;
&lt;li&gt;在一個包含 1,000,000 行的表中，它只需要大約 3.2 % 的異動，即可觸發自動更新統計信息。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
注意事項&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;從 SQL Server 2016 (13.x) 開始及根據資料庫相容性層級 130，此行為由引擎控制，追蹤旗標 2371 沒有任何作用。&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;01_COMPATIBILITY_LEVEL 130&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWhigz_STOoCpl8HnJQpPC5Eq3jLbug5SQRtNivfZa7eF4qOm9tJtNNc7InVxighUBFfE5UFNdU99WQ1BBFkfn9rpLtjJ7Aooc2dwZOj4cO9AoN3uZK15MuucDHs0kO7tyqFWpX8QW7yA/s1600/01_COMPATIBILITY_LEVEL+130.png" imageanchor="1"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWhigz_STOoCpl8HnJQpPC5Eq3jLbug5SQRtNivfZa7eF4qOm9tJtNNc7InVxighUBFfE5UFNdU99WQ1BBFkfn9rpLtjJ7Aooc2dwZOj4cO9AoN3uZK15MuucDHs0kO7tyqFWpX8QW7yA/s400/01_COMPATIBILITY_LEVEL+130.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 建立資料表 Statistics_100K&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;建立資料表: Statistics_100K。&lt;/li&gt;
&lt;li&gt;建立 Primary Key 與 Clustered Index 在 column: rid。&lt;/li&gt;
&lt;li&gt;新增 10 萬筆資料列。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;02_Create Table Statistics_100K&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKFfg523g9ZzJusZOjdg06-zLWfhF2U7Byy5N2cTvtFAkyeO-Rz0st4jVHKePhrJoUWeZh9Wui1Kklj9ERrNElJrbd8mw4iBNnuhyphenhyphenTzEk7CAKwl_a92Bj9JzpE-UOtQfpTbUPMRFXTEUk/s1600/02_Create+Table+Statistics_100K.png" imageanchor="1"&gt;&lt;img border="0" height="430" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKFfg523g9ZzJusZOjdg06-zLWfhF2U7Byy5N2cTvtFAkyeO-Rz0st4jVHKePhrJoUWeZh9Wui1Kklj9ERrNElJrbd8mw4iBNnuhyphenhyphenTzEk7CAKwl_a92Bj9JzpE-UOtQfpTbUPMRFXTEUk/s640/02_Create+Table+Statistics_100K.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 使用 dm_db_stats_properties: 傳回 資料表 的所有 Statistics 屬性&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;dm_db_stats_properties: SQL Server 2008 版本提供，可用於 傳回 資料表 的所有 統計資料 屬性。&lt;/li&gt;
&lt;li&gt;建立 Clustered Index 在 column: rid，系統自動一併建立 Statistics: PK_Statistics_100K_rid。&lt;/li&gt;
&lt;li&gt;但 Statistics 目前都是 NULL，尚未產生。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: sql"&gt;-- dm_db_stats_properties: Returns properties of statistics for the specified database object

SELECT sch.name [Schema], t.name [Table], c.name [Column], stat.stats_id, stat.name [Statistics], sp.last_updated, 
 sp.rows, sp.rows_sampled, sp.steps, sp.unfiltered_rows, stat.filter_definition, sp.modification_counter, 
 stat.auto_created, stat.user_created
FROM sys.stats stat CROSS APPLY sys.dm_db_stats_properties(stat.object_id, stat.stats_id) sp
 INNER JOIN sys.tables t ON t.object_id = stat.object_id
 INNER JOIN sys.stats_columns sc ON (sc.stats_id = sp.stats_id AND sp.object_id = sc.object_id)
 INNER JOIN sys.columns c ON (c.column_id = sc.column_id AND c.object_id = t.object_id)
 INNER JOIN sys.schemas sch ON t.schema_id = sch.schema_id
WHERE t.name = 'Statistics_100K';  
GO
&lt;/pre&gt;
&lt;br /&gt;
-- figure&amp;nbsp;03_dm_db_stats_properties&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpOmVXqH1kO-IrqpSN9Xb7bcYl12M-T_750ic839UH2zg8rDpg9W1WHynHJE_sntVvPleFU81L6B_v2Y3Z85HcNo5lV8mjQsYE2zd4LGyJkeXVzuunDabZmTKSgEcBq2qtV-aefk6G_E4/s1600/03_dm_db_stats_properties.png" imageanchor="1"&gt;&lt;img border="0" height="194" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpOmVXqH1kO-IrqpSN9Xb7bcYl12M-T_750ic839UH2zg8rDpg9W1WHynHJE_sntVvPleFU81L6B_v2Y3Z85HcNo5lV8mjQsYE2zd4LGyJkeXVzuunDabZmTKSgEcBq2qtV-aefk6G_E4/s640/03_dm_db_stats_properties.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
04. 使用 SSMS 檢視 Index 與 Statistics。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;04_Primary_Key_Index_Statisitics&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxS8WVerqUj1_QCXgjftEKOE4e5qdvheXQvQOsx2NFhfCxrWqmAJNLyP1XIJ4mhNOz7SKWcuSSdosW1NGST7hqP7TRopOgatcI4DxQ_EIBDXvgAda9hl-JSC41Cvy-JWGyI3-HjWh_7lo/s1600/04_Primary_Key_Index_Statisitics.png" imageanchor="1"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxS8WVerqUj1_QCXgjftEKOE4e5qdvheXQvQOsx2NFhfCxrWqmAJNLyP1XIJ4mhNOz7SKWcuSSdosW1NGST7hqP7TRopOgatcI4DxQ_EIBDXvgAda9hl-JSC41Cvy-JWGyI3-HjWh_7lo/s1600/04_Primary_Key_Index_Statisitics.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
05. 自動產生 Statistics。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;依據預設值，有啟用資料庫選項：AUTO_CREATE_STATISTICS。&lt;/li&gt;
&lt;li&gt;WHERE 條件式使用 Column: Cdata，Query Optimizer 將自動為其建立 Statistics。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;AUTO_CREATE_STATISTICS&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;查詢最佳化工具會視需要針對查詢述詞中的單一資料行建立統計資料，以便改善查詢計劃和查詢效能。&amp;nbsp;&lt;/li&gt;
&lt;li&gt;這些單一資料行統計資料是在查詢最佳化工具編譯查詢時所建立的。&amp;nbsp;&lt;/li&gt;
&lt;li&gt;它只會針對尚未成為現有統計資料物件之第一個資料行的資料行建立單一資料行統計資料。&lt;/li&gt;
&lt;li&gt;預設值是 ON。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;05_Auto Create Statistics_ Cdata column&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9Rz4DF0s0qnuL7agxWWiVwEczfeH3DWgHMVzBS4fGYiBg2TAMBtTbrJ8XeDUFPXuoNYv3waw78R3oBsSd1FvgGB9bEmB387p-mbm4Y_USjr7DSEtKqDXCUWXHRgWjASry2CKHv8mqxQA/s1600/05_Auto+Create+Statistics_+Cdata+column.png" imageanchor="1"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9Rz4DF0s0qnuL7agxWWiVwEczfeH3DWgHMVzBS4fGYiBg2TAMBtTbrJ8XeDUFPXuoNYv3waw78R3oBsSd1FvgGB9bEmB387p-mbm4Y_USjr7DSEtKqDXCUWXHRgWjASry2CKHv8mqxQA/s1600/05_Auto+Create+Statistics_+Cdata+column.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
06. 檢查 資料表上的 Statistics。&lt;br /&gt;
&lt;br /&gt;
自動建立 Statistics: _WA_Sys_00000003_55DFB4D9&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Column: Cdata&lt;/li&gt;
&lt;li&gt;rows: 100000&lt;/li&gt;
&lt;li&gt;rows_sampled: 89782&lt;/li&gt;
&lt;li&gt;steps： 154&lt;/li&gt;
&lt;li&gt;unfiltered_rows: 100000&lt;/li&gt;
&lt;li&gt;modification_counter: 0&lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;auto_created: 1&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
注意：&lt;br /&gt;
Statistics: PK_Statistics_100K_rid 內容值尚未產生，仍是 NULL&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;06_dm_db_stats_properties&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBMROCmPHb8S8LMGf_7MSmTm3zIyQ6JOg06hHMHmWhfIP1GipbY7uMnpVpitMgATa7XyIIXFe4ga0QCrvqXM49dNbWBr4uCBw4IziO_y3YZYSxxNSOfioXkknJq948FA6eKgfWT8Tul88/s1600/06_dm_db_stats_properties.png" imageanchor="1"&gt;&lt;img border="0" height="64" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBMROCmPHb8S8LMGf_7MSmTm3zIyQ6JOg06hHMHmWhfIP1GipbY7uMnpVpitMgATa7XyIIXFe4ga0QCrvqXM49dNbWBr4uCBw4IziO_y3YZYSxxNSOfioXkknJq948FA6eKgfWT8Tul88/s640/06_dm_db_stats_properties.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
07. 使用 SSMS 檢視 Index 與 Statistics。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;已經新增第 2 個 Statistics: _WA_Sys_00000003_55DFB4D9&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;07_SSMS_Statistics&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3t_btb7Ew3SpCRMqHHsqB26-XKQ5Y1hnLQ1o6inn4qFLNCPedrU59LOFc323SLjFJW9FFdKGlyWVDiDSXZIFTyf4d99phgb5R4PnMORQsgCWQHmURVdeqrN5K7EiLMC7DLoP5qVv8hCc/s1600/07_SSMS_Statistics.png" imageanchor="1"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3t_btb7Ew3SpCRMqHHsqB26-XKQ5Y1hnLQ1o6inn4qFLNCPedrU59LOFc323SLjFJW9FFdKGlyWVDiDSXZIFTyf4d99phgb5R4PnMORQsgCWQHmURVdeqrN5K7EiLMC7DLoP5qVv8hCc/s400/07_SSMS_Statistics.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
08.&amp;nbsp;檢視 Statistics 的 Details 頁籤。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Statistics: PK_Statistics_100K_rid&amp;nbsp;內容值尚未產生，仍是 NULL&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;08_Statistics_Detail_NULL&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiGl4bSD9mHImw3SqHBw7O63Vwm0gtWSmE6EIekEe2xX8lCrxNicYxvK6DHLa9gcMDaIKIzNfMNb4z8QQxtIvI346mGbTctL4LWGemvV7v4RgKwRZmJbg-A2y5kwGiQbBg6ywxH7guNMY/s1600/08_Statistics_Detail_NULL.png" imageanchor="1"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiGl4bSD9mHImw3SqHBw7O63Vwm0gtWSmE6EIekEe2xX8lCrxNicYxvK6DHLa9gcMDaIKIzNfMNb4z8QQxtIvI346mGbTctL4LWGemvV7v4RgKwRZmJbg-A2y5kwGiQbBg6ywxH7guNMY/s1600/08_Statistics_Detail_NULL.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
09. 檢視 Statistics 的 Details 頁籤。&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Statistics: _WA_Sys_00000003_55DFB4D9&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;09_Auto_Create_Statistics_Detail_Data&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCihoLqKBz7yeJW5GoBJtJUWQ11X5C1faxL5f5RY5gheE6bwpK8a0F8L8AOQLMuBZ-uqRxyaankC-2dHwtITeLcyXsErZfdPoq8cEudvqMLzHJQj_in8q7hEGpV8sUb0uQ9PbjR27gjew/s1600/09_Auto_Create_Statisics_Detail_Data.png" imageanchor="1"&gt;&lt;img border="0" height="582" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCihoLqKBz7yeJW5GoBJtJUWQ11X5C1faxL5f5RY5gheE6bwpK8a0F8L8AOQLMuBZ-uqRxyaankC-2dHwtITeLcyXsErZfdPoq8cEudvqMLzHJQj_in8q7hEGpV8sUb0uQ9PbjR27gjew/s640/09_Auto_Create_Statisics_Detail_Data.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
10. 使用 DBCC SHOW_STATISTICS 與 WITH STAT_HEADER&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;DBCC SHOW_STATISTICS 可檢視指定 Index, Statistics, Column 的統計資訊。&lt;/li&gt;
&lt;li&gt;WITH STAT_HEADER，僅檢視 STAT_HEADER。&lt;/li&gt;
&lt;li&gt;與 dm_db_stats_properties 結果相同。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;10_DBCC SHOW_STATISTICS_WITH STAT_HEADER&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikcFjeUC7Ja7y6zTUyI3tjkniRvDBRwQ8b83ChAijhYPbzVkrYDcLjuate3zxrzMjAYlMnf6DMIgHRM2D_XyTVbQpyon6LYuu3XuhCGnyyZB-SSQeH0u6wqHc6uXDzRtaPTTt4gkdA8gM/s1600/10_DBCC+SHOW_STATISTICS_WITH+STAT_HEADER.png" imageanchor="1"&gt;&lt;img border="0" height="118" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikcFjeUC7Ja7y6zTUyI3tjkniRvDBRwQ8b83ChAijhYPbzVkrYDcLjuate3zxrzMjAYlMnf6DMIgHRM2D_XyTVbQpyon6LYuu3XuhCGnyyZB-SSQeH0u6wqHc6uXDzRtaPTTt4gkdA8gM/s640/10_DBCC+SHOW_STATISTICS_WITH+STAT_HEADER.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
11. 建立 Create NonClustered Index on [TransactionID]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;11_Create NonClustered Index on [TransactionID]&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLvL6pkxKJkxJvx7GRLDPIvdMrSQwgjI4i_-W9Rz4nvQyw2s3f-rG4ut1E7G_yS4HQl62YAYdf6E-yOikQ4FewYwfQmRsARZz2PsnRLW-Gvn1YxpIx4MvKQzT69oqVBHmyz2qdIlhGPaQ/s1600/11_Create+NonClustered+Index+on+%255BTransactionID%255D.png" imageanchor="1"&gt;&lt;img border="0" height="148" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLvL6pkxKJkxJvx7GRLDPIvdMrSQwgjI4i_-W9Rz4nvQyw2s3f-rG4ut1E7G_yS4HQl62YAYdf6E-yOikQ4FewYwfQmRsARZz2PsnRLW-Gvn1YxpIx4MvKQzT69oqVBHmyz2qdIlhGPaQ/s640/11_Create+NonClustered+Index+on+%255BTransactionID%255D.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
12. 檢視 Statistics：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;產生第 3 個 statistics。&lt;/li&gt;
&lt;li&gt;建立 Index，系統自動建立對應的 Statistics: IX_Statistics_100K_TransactionID。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
Statistics: IX_Statistics_100K_TransactionID&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Column: TransactionID&lt;/li&gt;
&lt;li&gt;rows: 100000&lt;/li&gt;
&lt;li&gt;rows_sampled:100000&lt;/li&gt;
&lt;li&gt;steps：2&lt;/li&gt;
&lt;li&gt;unfiltered_rows: 100000&lt;/li&gt;
&lt;li&gt;modification_counter: 0&lt;/li&gt;
&lt;li&gt;auto_created: 0&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
注意：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;PK_Statistics_100K_rid 尚未產生 Statistics&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;12_建立 Index_系統自動建立對應的 Statistics&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBp1ntjekuvEPtE3xivwsjJ9iCoAVv_75fjbpATrZkVB1Mj_0FCnWsvdfQ-mXkEe-HBzyCaKt4wgPyNsI673g82p7p6ruxsBhQwjQ-WxDzIzTZ2-uBAYqC3ijYG8xsy76ZJeBBQDTUtPQ/s1600/12_dm_db_stats_properties.png" imageanchor="1"&gt;&lt;img border="0" height="64" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBp1ntjekuvEPtE3xivwsjJ9iCoAVv_75fjbpATrZkVB1Mj_0FCnWsvdfQ-mXkEe-HBzyCaKt4wgPyNsI673g82p7p6ruxsBhQwjQ-WxDzIzTZ2-uBAYqC3ijYG8xsy76ZJeBBQDTUtPQ/s640/12_dm_db_stats_properties.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
13. 使用 SSMS 檢視 Index 與 Statistics。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;已經新增第 3 個 Statistics: IX_Statistics_100K_TransactionID&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;13_Index_Statistics&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1TarI6mPCuSuw945BbktK3rz3UJltCNXXQH2JqsfvdWSbZDU6lDCdYAWoh1bEmrWQ3xp4Ile3tUzYkt9fkm7b_9Yy5YIJ_YTNMJA8nwoqOLhYEV-a3HsQy6phUF9VCNWl3boTHd6LLLc/s1600/13_Index_Statistics.png" imageanchor="1"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1TarI6mPCuSuw945BbktK3rz3UJltCNXXQH2JqsfvdWSbZDU6lDCdYAWoh1bEmrWQ3xp4Ile3tUzYkt9fkm7b_9Yy5YIJ_YTNMJA8nwoqOLhYEV-a3HsQy6phUF9VCNWl3boTHd6LLLc/s1600/13_Index_Statistics.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
14. 使用 DBCC SHOW_STATISTICS 與 WITH STAT_HEADER&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;檢視 指定 Statistics: IX_Statistics_100K_TransactionID 的統計資訊&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;14_DBCC SHOW_STATISTICS_WITH STAT_HEADER&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6Bg3V0CZaBCYY2OpjOlWH9uCp2-T4o-mhPD5vc3QCX3w4c8fytEndqHt7U-4Jmv8KyWaLs5E39sbM3M3cIA1aB1Cts4W5NY1z1vgmOYwtgXnS6mcPtdbT4oYNo3oMWtuIfxWRbYirBZg/s1600/14_DBCC+SHOW_STATISTICS_WITH+STAT_HEADER.png" imageanchor="1"&gt;&lt;img border="0" height="52" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6Bg3V0CZaBCYY2OpjOlWH9uCp2-T4o-mhPD5vc3QCX3w4c8fytEndqHt7U-4Jmv8KyWaLs5E39sbM3M3cIA1aB1Cts4W5NY1z1vgmOYwtgXnS6mcPtdbT4oYNo3oMWtuIfxWRbYirBZg/s320/14_DBCC+SHOW_STATISTICS_WITH+STAT_HEADER.png" width="320" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Dynamic auto update statistics threshold 動態 自動更新統計資料閾值&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;認識 AUTO_UPDATE_STATISTICS 自動更新統計資料&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;從 SQL Server 2016 (13.x) 開始，並 在資料庫相容性層級 130，&amp;nbsp;&lt;/li&gt;
&lt;li&gt;採用 Dynamic auto update statistics threshold(動態 自動更新統計資料閾值)&lt;/li&gt;
&lt;li&gt;SQL Server 會使用降低、動態的統計資料更新臨界值。此臨界值會根據資料表中的資料列數目來做出調整。&amp;nbsp;&lt;/li&gt;
&lt;li&gt;這是以 1000 乘以目前資料表基數的平方根來計算。&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;例如，如果您的資料表包含 2 百萬個資料列，則計算結果是 SQRT(1000 * 2000000) = 44721.359。&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
透過這項變更，大型資料表上的統計資料會經常更新。&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
不過，如果資料庫的相容性層級低於 130，便會套用 SQL Server 2014 (12.x) 臨界值。&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="color: blue; font-size: large;"&gt;追蹤旗標 2371&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;在資料庫相容性層級 低於 130 之下，從 SQL Server 2008 R2 開始至 SQL Server 2014 (12.x)。&lt;/li&gt;
&lt;li&gt;或是，從 SQL Server 2016 (13.x) 至 SQL Server 2017，使用追蹤旗標 2371 時，&amp;nbsp;&lt;/li&gt;
&lt;li&gt;SQL Server 就會使用降低、動態的統計資料更新臨界值。此臨界值會根據資料表中的資料列數目來做出調整。&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
對於較小的表格，閾值仍將是大約 20% 的百分比。&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
當每個表超過 25,000 行時，動態規則才會啟動，並且隨著行數的增加，更改的記錄百分比變得越來越低。&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
例如&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;在具有 100,000 行的表中，觸發更新統計信息的閾值已降至 10 %。&lt;/li&gt;
&lt;li&gt;在一個包含 1,000,000 行的表中，它只需要大約 3.2 % 的異動，即可觸發自動更新統計信息。&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
以本案例來看：&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;資料表有 10 萬筆資料列，若要達到自動更新統計資訊的 threshold&lt;/li&gt;
&lt;li&gt;需要有 10, 000 筆以上被異動。&lt;/li&gt;
&lt;li&gt;計算： SELECT SQRT (1000 * 100000) = 10000&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
-- figure&amp;nbsp;52_Threshold&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPHL8zrb1wqIhLdPaN_AL4b7vZ517K-9Y-STuh9X7WYXqRgqrlb1ARhDQ_zNVl11oGaQlXOAE-Nvq-lf0Eace-D3dO9r-j8HhmQwZF4yxs8kMo5WWPquHBbDQ3p-mRqmRt9IsJYeiKPME/s1600/52_Threshold.png" imageanchor="1"&gt;&lt;img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPHL8zrb1wqIhLdPaN_AL4b7vZ517K-9Y-STuh9X7WYXqRgqrlb1ARhDQ_zNVl11oGaQlXOAE-Nvq-lf0Eace-D3dO9r-j8HhmQwZF4yxs8kMo5WWPquHBbDQ3p-mRqmRt9IsJYeiKPME/s640/52_Threshold.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
01. 本次案例，所使用的 SQL Query：&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;資料表有 10 萬筆，回傳 10,310 筆。&lt;/li&gt;
&lt;li&gt;Clustered Index Scan, Return 10,310&amp;nbsp;rows&lt;/li&gt;
&lt;li&gt;TransactionID &amp;lt; 110311&lt;/li&gt;
&lt;li&gt;Execution Plan: &lt;span style="color: red;"&gt;Missing Index&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
-- figure&amp;nbsp;21_常用的 Query 與 條件式&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggv4lWfu-tiYAkUfXbAMxlFxpKntoilxfalDR3hyPCKLiwnyaKb_iqK9zuq-IqX6jxgUZAwxunrAJ_S-V5OimPazzsQbdrl9usDQK_EYPI1WibvPFdveZZE4TznR7vr6UiHIJBibgfYlg/s1600/21_%25E5%25B8%25B8%25E7%2594%25A8%25E7%259A%2584+Query+%25E8%2588%2587+%25E6%25A2%259D%25E4%25BB%25B6%25E5%25BC%258F.png" imageanchor="1"&gt;&lt;img border="0" height="552" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggv4lWfu-tiYAkUfXbAMxlFxpKntoilxfalDR3hyPCKLiwnyaKb_iqK9zuq-IqX6jxgUZAwxunrAJ_S-V5OimPazzsQbdrl9usDQK_EYPI1WibvPFdveZZE4TznR7vr6UiHIJBibgfYlg/s640/21_%25E5%25B8%25B8%25E7%2594%25A8%25E7%259A%2584+Query+%25E8%2588%2587+%25E6%25A2%259D%25E4%25BB%25B6%25E5%25BC%258F.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 有 Missing Index&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;22_Missing_Index&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqKlRn_ucuM5eDNcy0MERBEqIcXQffghH-7VD5cXwzE9mHSsn-JhYHbFXTzEYb6t4A_s623-icuQDaTVnC9DxfgCmYlaTy4VUvfqxuZIJ_jDfJf3p23WcDD8HesMAdlfRr21-iF-o9AJM/s1600/22_Missing_Index.png" imageanchor="1"&gt;&lt;img border="0" height="398" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqKlRn_ucuM5eDNcy0MERBEqIcXQffghH-7VD5cXwzE9mHSsn-JhYHbFXTzEYb6t4A_s623-icuQDaTVnC9DxfgCmYlaTy4VUvfqxuZIJ_jDfJf3p23WcDD8HesMAdlfRr21-iF-o9AJM/s640/22_Missing_Index.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
檢視 Execution Plan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Cluster Index Scan&lt;/li&gt;
&lt;li&gt;Reads: 1,289&lt;/li&gt;
&lt;li&gt;Est Rows: 10,310&lt;/li&gt;
&lt;li&gt;Actual Rows: 10,310&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;23_Plan_Explorer&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRxpb4Jw6jEGgLCsRtcE2H-IZ2Rds9EDwQ1Pkx5e4ROJJ5KfYcGyWlFe_OUkoTPLYLehPo7Vy7G7974VikNhnfEdoE4nPHDSGE4BCDkHejZm6TpgEOzRjKz4u80LFgBoY3wz16O_tsc2M/s1600/23_Plan_Explorer.png" imageanchor="1"&gt;&lt;img border="0" height="176" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRxpb4Jw6jEGgLCsRtcE2H-IZ2Rds9EDwQ1Pkx5e4ROJJ5KfYcGyWlFe_OUkoTPLYLehPo7Vy7G7974VikNhnfEdoE4nPHDSGE4BCDkHejZm6TpgEOzRjKz4u80LFgBoY3wz16O_tsc2M/s640/23_Plan_Explorer.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 刪除資料&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;刪除 10,300 筆。&lt;/li&gt;
&lt;li&gt;已達到 更新 Statistics 的 threshold(臨界值)&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
SQL Server 2016(13.x) 版本，改為以 1000 乘以目前資料表基數的平方根來計算&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;This is calculated as the square root of the product of 1000 and the current table cardinality.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;SELECT SQRT (1000 * 100000) = 10000&lt;/li&gt;
&lt;li&gt;TransactionID &amp;lt; 110301&lt;/li&gt;
&lt;li&gt;Return 10,300 rows&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;24_Modify Data to over threshold_SQRT&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVRJdUm4gasZx2J6XC3E3oDWXN4MqQCamvMWEY-GN3gDEWoFC1Ak7NRhEJO9YlPROgjVbULO2xjX31TyK4xh0FHmg-aSio9KtpygJDtrvEfZu6YtD96A8f_4u_vzr2yo_dGQaH69TBmYg/s1600/24_Modify+Data+to+over+threshold_SQRT.png" imageanchor="1"&gt;&lt;img border="0" height="424" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVRJdUm4gasZx2J6XC3E3oDWXN4MqQCamvMWEY-GN3gDEWoFC1Ak7NRhEJO9YlPROgjVbULO2xjX31TyK4xh0FHmg-aSio9KtpygJDtrvEfZu6YtD96A8f_4u_vzr2yo_dGQaH69TBmYg/s640/24_Modify+Data+to+over+threshold_SQRT.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
04. 檢視 Statistics：&lt;br /&gt;
&lt;br /&gt;
超過 臨界值，但 Statistics 仍未改變 !&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Statistics: IX_Statistics_100K_TransactionID&lt;/li&gt;
&lt;li&gt;Column: TransactionID&lt;/li&gt;
&lt;li&gt;rows: 100000&lt;/li&gt;
&lt;li&gt;rows_sampled:100000&lt;/li&gt;
&lt;li&gt;steps：2&lt;/li&gt;
&lt;li&gt;unfiltered_rows: 100000&lt;/li&gt;
&lt;li&gt;modification_counter: &lt;span style="color: blue;"&gt;10300&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;auto_created: 0&lt;/li&gt;
&lt;li&gt;Total: 89,700 rows: SELECT 100000 - 10300 -- 89700&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;25_dm_db_stats_properties_超過 臨界值，但 Statistics 仍未改變&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWkFdZpoHm9STEUs1p1_fWh6A0uzjZJFZwXx28e6v6LfGnJqiB-4DCE9ZIetmgStsc0Ok6smdGZJk0is1ndLphU0vJIMt-gKv98LyHkd7TZoT37eQ_Ui1xD62T-dahqp3vamJlefcOvnY/s1600/25_dm_db_stats_properties_%25E8%25B6%2585%25E9%2581%258E+%25E8%2587%25A8%25E7%2595%258C%25E5%2580%25BC%25EF%25BC%258C%25E4%25BD%2586+Statistics+%25E4%25BB%258D%25E6%259C%25AA%25E6%2594%25B9%25E8%25AE%258A.png" imageanchor="1"&gt;&lt;img border="0" height="60" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWkFdZpoHm9STEUs1p1_fWh6A0uzjZJFZwXx28e6v6LfGnJqiB-4DCE9ZIetmgStsc0Ok6smdGZJk0is1ndLphU0vJIMt-gKv98LyHkd7TZoT37eQ_Ui1xD62T-dahqp3vamJlefcOvnY/s640/25_dm_db_stats_properties_%25E8%25B6%2585%25E9%2581%258E+%25E8%2587%25A8%25E7%2595%258C%25E5%2580%25BC%25EF%25BC%258C%25E4%25BD%2586+Statistics+%25E4%25BB%258D%25E6%259C%25AA%25E6%2594%25B9%25E8%25AE%258A.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
使用 使用 DBCC SHOW_STATISTICS 與 WITH STAT_HEADER&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;26_DBCC SHOW_STATISTICS_WITH STAT_HEADER&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjeyb2CWGaH2ZPYEz2BZLRPndxGeH92H1m72SFqYPTB0BtWR7Vz9xAtntZ7eJrljq0NpyQkF7EqR_B6PCwhOpvpu1sgZxB7WHJKks1pBBUi6C2jwvk8QDyMp-rtiOfZPaeVXztJfPu33c/s1600/26_DBCC+SHOW_STATISTICS_WITH+STAT_HEADER.png" imageanchor="1"&gt;&lt;img border="0" height="128" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjeyb2CWGaH2ZPYEz2BZLRPndxGeH92H1m72SFqYPTB0BtWR7Vz9xAtntZ7eJrljq0NpyQkF7EqR_B6PCwhOpvpu1sgZxB7WHJKks1pBBUi6C2jwvk8QDyMp-rtiOfZPaeVXztJfPu33c/s640/26_DBCC+SHOW_STATISTICS_WITH+STAT_HEADER.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
05. 再度執行 SQL Query&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;何時自動更新 AUTO_UPDATE_STATISTICS ?&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;開啟自動更新統計資料選項 AUTO_UPDATE_STATISTICS 時，Query Optimizer 會判斷 statistics 何時過期，然後在查詢使用 statistics 時加以更新。&lt;/li&gt;
&lt;li&gt;在編譯查詢及執行快取 query plan 之前，Query Optimizer 會檢查是否有過期的 statistics 。&amp;nbsp;&lt;/li&gt;
&lt;li&gt;在編譯查詢之前，Query Optimizer 會使用查詢述詞中的資料行、資料表和索引檢視表來判斷哪些 statistics 可能已過期。&amp;nbsp;&lt;/li&gt;
&lt;li&gt;在執行快取 query plan 之前， Database Engine 會確認 query plan 是否參考最新的 statistics。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
換言之:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;statistics 過期後，要等到下次執行 Query(SIUD)， 查詢 statistics 時，一併更新 statistics。&lt;/li&gt;
&lt;li&gt;如果 statistics 已過期，Query Optimizer 就會先等候並執行更新 statistics，然後再 compile 並執行查詢。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;31_何時更新 statistics_下次執行 Query(SIUD)&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjw5nadqjwmSoKV3Y4MPYKZatW7irjUjR4u503JKxrgyxOZF4XMnsFEudxfvtjRYS00JgRngZ74SHU1AbBjy5egyD4NNyRqr9xBjsH_pgQyZ3-OL_8f6r9Aob7a6C1neI_MzkEfAKiWz2o/s1600/31_%25E4%25BD%2595%25E6%2599%2582%25E6%259B%25B4%25E6%2596%25B0+statistics_%25E4%25B8%258B%25E6%25AC%25A1%25E5%259F%25B7%25E8%25A1%258C+Query%2528SIUD%2529.png" imageanchor="1"&gt;&lt;img border="0" height="394" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjw5nadqjwmSoKV3Y4MPYKZatW7irjUjR4u503JKxrgyxOZF4XMnsFEudxfvtjRYS00JgRngZ74SHU1AbBjy5egyD4NNyRqr9xBjsH_pgQyZ3-OL_8f6r9Aob7a6C1neI_MzkEfAKiWz2o/s640/31_%25E4%25BD%2595%25E6%2599%2582%25E6%259B%25B4%25E6%2596%25B0+statistics_%25E4%25B8%258B%25E6%25AC%25A1%25E5%259F%25B7%25E8%25A1%258C+Query%2528SIUD%2529.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
改為使用 &lt;span style="color: blue;"&gt;Index Seek&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;32_何時更新 statistics_下次執行 Query(SIUD)&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVglgcRUnUbPSi808Q0ucOUtnoa2TsDUgsjHQMrBUFw6jk0tnKkbDYhD9tkZfdnAalFst7Z6KSsdqIzZiOMigR5-AHkqNKStUQp09daZa6zaira5I1egg6yYh2vYJCZWjyxxMGhmY6vBE/s1600/32_%25E4%25BD%2595%25E6%2599%2582%25E6%259B%25B4%25E6%2596%25B0+statistics_%25E4%25B8%258B%25E6%25AC%25A1%25E5%259F%25B7%25E8%25A1%258C+Query%2528SIUD%2529.png" imageanchor="1"&gt;&lt;img border="0" height="384" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVglgcRUnUbPSi808Q0ucOUtnoa2TsDUgsjHQMrBUFw6jk0tnKkbDYhD9tkZfdnAalFst7Z6KSsdqIzZiOMigR5-AHkqNKStUQp09daZa6zaira5I1egg6yYh2vYJCZWjyxxMGhmY6vBE/s640/32_%25E4%25BD%2595%25E6%2599%2582%25E6%259B%25B4%25E6%2596%25B0+statistics_%25E4%25B8%258B%25E6%25AC%25A1%25E5%259F%25B7%25E8%25A1%258C+Query%2528SIUD%2529.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
檢視 Execution Plan&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Index Seek&lt;/li&gt;
&lt;li&gt;Reads: 33&lt;/li&gt;
&lt;li&gt;Est Rows: 10&lt;/li&gt;
&lt;li&gt;Actual Rows: 10&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;33_Plan_Explorer&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPHY96cmvFezo3DAQ4DMuYdx1mUV_UGvvAzz7zECpsOJae8V4acGq9FiyxdasBd6vGRHcSNr44JPWWKQgICWjmHp1YFRtdmv0P0vlFH3DbwyV5smO8GNKdRhzt37D8dCFV7713Zvabx3k/s1600/33_Plan_Explorer.png" imageanchor="1"&gt;&lt;img border="0" height="214" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPHY96cmvFezo3DAQ4DMuYdx1mUV_UGvvAzz7zECpsOJae8V4acGq9FiyxdasBd6vGRHcSNr44JPWWKQgICWjmHp1YFRtdmv0P0vlFH3DbwyV5smO8GNKdRhzt37D8dCFV7713Zvabx3k/s640/33_Plan_Explorer.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
06. 檢視 Statistics&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
Statistics 已經更新&lt;/div&gt;
&lt;div&gt;
modification_counter: &lt;span style="color: blue;"&gt;0&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
(1) Statistics: IX_Statistics_100K_TransactionID&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;Column: TransactionID&lt;/li&gt;
&lt;li&gt;rows: 89700&lt;/li&gt;
&lt;li&gt;rows_sampled:88296&lt;/li&gt;
&lt;li&gt;steps：80&lt;/li&gt;
&lt;li&gt;unfiltered_rows: 89700&lt;/li&gt;
&lt;li&gt;modification_counter: 0&lt;/li&gt;
&lt;li&gt;auto_created: 0&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
(2) Statistics: PK_Statistics_100K_rid &lt;span style="color: red;"&gt;尚未產生 Statistics&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
(3) _WA_Sys_00000003_55DFB4D9 &lt;span style="color: red;"&gt;仍是未更新&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
-- figure&amp;nbsp;34_dm_db_stats_properties&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHHqlIoCiklMA02IRR1GqLsx_bTC1drJM6F6ULnUbeHh_ouj_j72QvT0zujPn8oj-MevgDrqkB9tsi6Lkt-Z91G3Ve3Jk7Ihsxbb-tiAimMyvN5z81wXW61Zn9vbcaoHUIGLrwXmJ8c7Q/s1600/34_dm_db_stats_properties.png" imageanchor="1"&gt;&lt;img border="0" height="188" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHHqlIoCiklMA02IRR1GqLsx_bTC1drJM6F6ULnUbeHh_ouj_j72QvT0zujPn8oj-MevgDrqkB9tsi6Lkt-Z91G3Ve3Jk7Ihsxbb-tiAimMyvN5z81wXW61Zn9vbcaoHUIGLrwXmJ8c7Q/s640/34_dm_db_stats_properties.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
07. 使用 DBCC SHOW_STATISTICS 與 WITH STAT_HEADER&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;檢視 指定 Statistics: IX_Statistics_100K_TransactionID 的統計資訊&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;35_DBCC SHOW_STATISTICS_WITH STAT_HEADER&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgv1BKI06yHQNKaeBiAFHcomAbeVhDD0ZYt8dW55bSJO1IEHcrxoDvh2HJghY0ZE5ZQ26FJ6GzO0YGGDqSLSfz2sBsWQS5SQ5s2Sc3FylgfhOGqYTH8r4MU50VZ2NpZjherq43oLpEA5GI/s1600/35_DBCC+SHOW_STATISTICS_WITH+STAT_HEADER.png" imageanchor="1"&gt;&lt;img border="0" height="122" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgv1BKI06yHQNKaeBiAFHcomAbeVhDD0ZYt8dW55bSJO1IEHcrxoDvh2HJghY0ZE5ZQ26FJ6GzO0YGGDqSLSfz2sBsWQS5SQ5s2Sc3FylgfhOGqYTH8r4MU50VZ2NpZjherq43oLpEA5GI/s640/35_DBCC+SHOW_STATISTICS_WITH+STAT_HEADER.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;Statistics 更新前後的比較&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;table border="1" cellpadding="1" cellspacing="1"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;Before&lt;/td&gt;&lt;td&gt;After&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Index&lt;/td&gt;&lt;td&gt;Clustered Index&amp;nbsp;&lt;span style="color: red;"&gt;Scan&lt;/span&gt;&lt;/td&gt;&lt;td&gt;Index&amp;nbsp;&lt;span style="color: blue;"&gt;Seek&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;&lt;span style="color: red;"&gt;1,289&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="color: blue;"&gt;33&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Est Rows&lt;/td&gt;&lt;td&gt;&lt;span style="color: red;"&gt;10,310&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="color: blue;"&gt;10&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
更新過的 Statistics，能夠反映實際的資料特性，幫助 Query Optimizer 選擇合適的 Index。&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;若以 Read IO 來看，更新 Statistics 後，幫助 Query Optimizer 選擇合適的 Index&lt;/li&gt;
&lt;li&gt;效能提升：97.44 %。&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
SELECT ABS(33-1289)/1289.0 * 100 -- 97.439800&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Sample Code&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
20181011_Use Autostat (AUTO_UPDATE_STATISTICS)&lt;br /&gt;
&lt;a href="https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing"&gt;https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Reference&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Use Autostat (AUTO_UPDATE_STATISTICS), 認識 自動更新統計資料 (1)&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/10/statistics-use-autostat.html"&gt;http://sharedderrick.blogspot.com/2018/10/statistics-use-autostat.html&lt;/a&gt;</description><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXhiRbwfH_-QnprnIusBHSEhRSkpVwj2FeAdpdkLkSctDCkoGWZkvhyACizwPGyDkM3v-cjhdtUM_kSJ7KVumIxJduDblCaA-DX8cLn3jztJTLZCnsd0vzAe7StXsWdmZP_NK5k2nwf6I/s72-c/53_Excel_Threshold.png" width="72"/><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><title>Use Autostat (AUTO_UPDATE_STATISTICS), 認識 自動更新統計資料 (1)</title><link>http://sharedderrick.blogspot.com/2018/10/statistics-use-autostat.html</link><category>Performance Tuning</category><category>SQL Server</category><author>noreply@blogger.com (DerrickLaLa)</author><pubDate>Thu, 11 Oct 2018 00:42:00 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1420955872914622499.post-2571699525342964739</guid><description>&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;(1) 更新 Statistics&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;更新過的 Statistics，能夠反映實際的資料特性，幫助 Query Optimizer 選擇合適的 Index。&lt;/li&gt;
&lt;li&gt;若 Statistics 尚未更新，導致 無法選擇更有效率的 Index。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;(2) 啟用 AUTO_UPDATE_STATISTICS&lt;/span&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Query Optimizer 會判斷 statistics 何時過期。&lt;/li&gt;
&lt;li&gt;statistics 過期後，要等到下次執行 Query(SIUD)， 查詢 statistics 時，一併更新 statistics。&lt;/li&gt;
&lt;li&gt;如果 statistics 已過期，Query Optimizer 就會先等候並執行更新 statistics，然後再 compile 並執行查詢。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;(3) Statistics 更新的 Threshold(臨界值)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
包含 SQL Server &lt;span style="color: blue;"&gt;&lt;b&gt;2014 (12.x)&lt;/b&gt;&lt;/span&gt;，以及先前版本，Statistics 更新的 Threshold是：&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;若 Table Cardinality(資料表基數) 在評估 Statistics&amp;nbsp; 時為 500 或更小的數值，將會在每 500 次修改之後更新。&lt;/li&gt;
&lt;li&gt;若資料表基數在評估 Statistics&amp;nbsp;時為超過 500 的數值，將會在每&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: blue; font-size: large;"&gt;&lt;b&gt;20% + 500&lt;/b&gt;&lt;/span&gt;&amp;nbsp;的修改次數之後更新。&lt;/li&gt;
&lt;li&gt;在 tempdb 資料庫中，如果資料表基數是小於 6，資料表的資料表每 6 修改，就會自動更新。&lt;/li&gt;
&lt;li&gt;Table Variables為基數的變更，不會觸發自動更新統計資料。&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;br /&gt;
例如：&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;資料表有 10 萬筆資料列，若要達到自動更新統計資訊的 臨界值&lt;/li&gt;
&lt;li&gt;需要有 20,500 筆以上被異動。&lt;/li&gt;
&lt;li&gt;計算：(100000 * 0.2) + 500 = 20500&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpC5jZzHNvjMWKVYN58K5ppgtnLXUDoFZwTAgBxi10giii_Y2ezL3lzpLVeqFdf5YVrV0zg4uALO_astMi-yUyAerRpZhJYrdtpPNbZU9REOHTJh2OC_4jpTlWJPerZ7eg4JeBh1ouY4M/s1600/61_dm_db_stats_properties.png" imageanchor="1"&gt;&lt;img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpC5jZzHNvjMWKVYN58K5ppgtnLXUDoFZwTAgBxi10giii_Y2ezL3lzpLVeqFdf5YVrV0zg4uALO_astMi-yUyAerRpZhJYrdtpPNbZU9REOHTJh2OC_4jpTlWJPerZ7eg4JeBh1ouY4M/s640/61_dm_db_stats_properties.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;(4) 建立 Index，系統自動建立對應的 Statistics。&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Statistics: Use Autostat (AUTO_UPDATE_STATISTICS ), 認識 自動更新統計資料&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
01. 檢查 COMPATIBILITY_LEVEL&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;確認 COMPATIBILITY_LEVEL = 120&lt;/li&gt;
&lt;li&gt;包含 SQL Server 2014 (12.x)，以及先前版本，會使用變更資料列的百分比作為臨界值。&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
Statistics 更新的 Threshold(臨界值)是：&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;若資料表基數在評估統計資料時為 500 或更小的數值，將會在每 500 次修改之後更新。&lt;/li&gt;
&lt;li&gt;若資料表基數在評估統計資料時為超過 500 的數值，將會在每&lt;span style="color: blue;"&gt; 20% + 500&lt;/span&gt; 的修改次數之後更新。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;01_COMPATIBILITY_LEVEL = 120&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihK2jN6hX973OBN0X9kIRjtQNESidIKRolTi4YDrZ8p-UL5xmMjGlq2EAayUI0tsRd7Xtb_gC1-IxgZZXF9w5TgIULFVmVkk-_BYPnxBi08YppIRToh0PzZ7P-rYBr_V8GOVpHUoZROco/s1600/01_COMPATIBILITY_LEVEL+%253D+120.png" imageanchor="1"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihK2jN6hX973OBN0X9kIRjtQNESidIKRolTi4YDrZ8p-UL5xmMjGlq2EAayUI0tsRd7Xtb_gC1-IxgZZXF9w5TgIULFVmVkk-_BYPnxBi08YppIRToh0PzZ7P-rYBr_V8GOVpHUoZROco/s1600/01_COMPATIBILITY_LEVEL+%253D+120.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
依據預設值，資料庫屬性：Auto Create Statistics 與 Auto Update Statistics 已經啟用。&lt;br /&gt;
&lt;br /&gt;
-- figure 檢視&amp;nbsp;Autostat&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgb3Q0LFJOga-hsL2RPgjRWwCkvL1xIb-S03PbX1vwmqntyWQBhjgRm5B8rQhoXb7Rs1XG6huoRBnvvIeXoBz9WEi8S2kaYdRr4T3V6tyrTdy0eg5b6TpvszrFdm0cHPTvRkRJt81QLoUg/s1600/51_Auto.png" imageanchor="1"&gt;&lt;img border="0" height="580" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgb3Q0LFJOga-hsL2RPgjRWwCkvL1xIb-S03PbX1vwmqntyWQBhjgRm5B8rQhoXb7Rs1XG6huoRBnvvIeXoBz9WEi8S2kaYdRr4T3V6tyrTdy0eg5b6TpvszrFdm0cHPTvRkRJt81QLoUg/s640/51_Auto.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 建立資料表 Statistics_100K&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;建立資料表: Statistics_100K。&lt;/li&gt;
&lt;li&gt;建立 Primary Key 與 Clustered Index 在 column: rid。&lt;/li&gt;
&lt;li&gt;新增 10 萬筆資料列。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;02_CREATE TABLE Statistics_100K - Insert&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6hv-w8Wejzi2clIWph-xKKiFqdRDRdpvNwjL0XRcxPEJpMuTzYxcvDXZZjzgQ2a2z6-3RC-nDM5RdV-qi29F-9Q7zGrNrID6HvVrNJCpOsiR7zwkKyrI68Wf_Hom1XGL1Zl9n3W-sHzs/s1600/02_CREATE+TABLE+Statistics_100K+-+Insert.png" imageanchor="1"&gt;&lt;img border="0" height="286" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6hv-w8Wejzi2clIWph-xKKiFqdRDRdpvNwjL0XRcxPEJpMuTzYxcvDXZZjzgQ2a2z6-3RC-nDM5RdV-qi29F-9Q7zGrNrID6HvVrNJCpOsiR7zwkKyrI68Wf_Hom1XGL1Zl9n3W-sHzs/s640/02_CREATE+TABLE+Statistics_100K+-+Insert.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 檢視資料特性：&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;03_View_Table_Data&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnT6W2gVwlLbh0NxU2MF3jztrCliMzq6NaK3Xbkt5-Edd5fICgItOPj45RBV7Ut3gjSKvn5Lbmbg7taiYKRWx2TDKBLACW-M3_Hj8KpqeyQaVhfaJhk1rNhp14pN5hKCcDumf6RmMgtVY/s1600/03_View_Table_Data.png" imageanchor="1"&gt;&lt;img border="0" height="352" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnT6W2gVwlLbh0NxU2MF3jztrCliMzq6NaK3Xbkt5-Edd5fICgItOPj45RBV7Ut3gjSKvn5Lbmbg7taiYKRWx2TDKBLACW-M3_Hj8KpqeyQaVhfaJhk1rNhp14pN5hKCcDumf6RmMgtVY/s640/03_View_Table_Data.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
04. 使用&amp;nbsp;dm_db_stats_properties: 傳回 資料表 的所有 Statistics 屬性&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;dm_db_stats_properties:&amp;nbsp;SQL Server 2008 版本提供，可用於 傳回 資料表 的所有 統計資料 屬性。&lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;建立 Clustered Index&amp;nbsp;在 column: rid，系統自動一併建立 Statistics: PK_Statistics_100K_rid。&lt;/span&gt;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;但 Statistics 目前都是 NULL，尚未產生。&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: sql"&gt;-- dm_db_stats_properties: Returns properties of statistics for the specified database object

SELECT sch.name [Schema], t.name [Table], c.name [Column], stat.stats_id, stat.name [Statistics], sp.last_updated, 
 sp.rows, sp.rows_sampled, sp.steps, sp.unfiltered_rows, stat.filter_definition, sp.modification_counter, 
 stat.auto_created, stat.user_created
FROM sys.stats stat CROSS APPLY sys.dm_db_stats_properties(stat.object_id, stat.stats_id) sp
 INNER JOIN sys.tables t ON t.object_id = stat.object_id
 INNER JOIN sys.stats_columns sc ON (sc.stats_id = sp.stats_id AND sp.object_id = sc.object_id)
 INNER JOIN sys.columns c ON (c.column_id = sc.column_id AND c.object_id = t.object_id)
 INNER JOIN sys.schemas sch ON t.schema_id = sch.schema_id
WHERE t.name = 'Statistics_100K';  
GO
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;04_dm_db_stats_properties_PK&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheZ8uAjK_vaqzU6CnwNCjPdOUB5EwHjVsyuhEkLnYVrUbLcrDikm4vTib1-nYPadecjQ4epHmGBWOwAW2KeC-4vnBHDDSn_ohEn4fHYWqh4PaPJYTRnAp1blrM5PofVZg3qXfAsXS6cx4/s1600/04_dm_db_stats_properties_PK.png" imageanchor="1"&gt;&lt;img border="0" height="222" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheZ8uAjK_vaqzU6CnwNCjPdOUB5EwHjVsyuhEkLnYVrUbLcrDikm4vTib1-nYPadecjQ4epHmGBWOwAW2KeC-4vnBHDDSn_ohEn4fHYWqh4PaPJYTRnAp1blrM5PofVZg3qXfAsXS6cx4/s640/04_dm_db_stats_properties_PK.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
05. 使用 SSMS 檢視 Index 與 Statistics。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;05_SSMS_Statistics&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2v-Sc4AeTlNhDa4xMX36dPQcdTRGjz6tGRYgWnA7ziOi3Dt9i4eP5Emk_XQ-rgpIUuWWHt0Gv98Aw2KVeOvYo4AZKgE6c-sBzZ3CI5EGMx2MdUizx8VR6grgFjyRFTUvlp_zyFcHMHVQ/s1600/05_SSMS_Statistics.png" imageanchor="1"&gt;&lt;img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2v-Sc4AeTlNhDa4xMX36dPQcdTRGjz6tGRYgWnA7ziOi3Dt9i4eP5Emk_XQ-rgpIUuWWHt0Gv98Aw2KVeOvYo4AZKgE6c-sBzZ3CI5EGMx2MdUizx8VR6grgFjyRFTUvlp_zyFcHMHVQ/s640/05_SSMS_Statistics.png" width="480" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
06. 自動產生 Statistics。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;依據預設值，有啟用資料庫選項：AUTO_CREATE_STATISTICS。&lt;/li&gt;
&lt;li&gt;WHERE 條件式使用 Column: Cdata，Query Optimizer 將自動為其建立 Statistics。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
AUTO_CREATE_STATISTICS&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;查詢最佳化工具會視需要針對查詢述詞中的單一資料行建立統計資料，以便改善查詢計劃和查詢效能。&amp;nbsp;&lt;/li&gt;
&lt;li&gt;這些單一資料行統計資料是在查詢最佳化工具編譯查詢時所建立的。&amp;nbsp;&lt;/li&gt;
&lt;li&gt;它只會針對尚未成為現有統計資料物件之第一個資料行的資料行建立單一資料行統計資料。&lt;/li&gt;
&lt;li&gt;預設值是 ON。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;06_Auto Create Statistics Cdata column&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkGBdUPHsc982KFhj9mc9TyiAVFWUmkeIG4OljkI_Lv-i9RcbBYFPDsdXwyECx_BGob_BGDH2kqMJZx59ISHp4xoehEquZnBiVOgodAc8PgWSx68nlDJMTrJVeRbGfCZERAaJJWaRus3w/s1600/06_Auto+Create+Statistics+Cdata+column.png" imageanchor="1"&gt;&lt;img border="0" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkGBdUPHsc982KFhj9mc9TyiAVFWUmkeIG4OljkI_Lv-i9RcbBYFPDsdXwyECx_BGob_BGDH2kqMJZx59ISHp4xoehEquZnBiVOgodAc8PgWSx68nlDJMTrJVeRbGfCZERAaJJWaRus3w/s640/06_Auto+Create+Statistics+Cdata+column.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
07. 檢查 資料表上的 Statistics。&lt;br /&gt;
&lt;br /&gt;
自動建立 Statistics: _WA_Sys_00000003_226010D3&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Column: Cdata&lt;/li&gt;
&lt;li&gt;rows: 100000&lt;/li&gt;
&lt;li&gt;rows_sampled: 88612&lt;/li&gt;
&lt;li&gt;steps： 131&lt;/li&gt;
&lt;li&gt;unfiltered_rows: 100000&lt;/li&gt;
&lt;li&gt;modification_counter: 0&lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;auto_created: 1&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
注意：&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Statistics: PK_Statistics_100K_rid 內容值尚未產生，仍是 NULL&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;07_自動建立 Statistics_但PK 還沒有產生 Statistics&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhavs33dO4MMIBh_lA6TS43WWvNVBT2WB9qfBykelnM6xsjc83Cr9wUhiEVca6u_mzWAvrzNeVMcU_idZMv_-q9Gb0u0e9zKpLBjTxlVvus3lvXtZw0b9kfWaDV1tzh50O3FBSLZBSShA0/s1600/07_%25E8%2587%25AA%25E5%258B%2595%25E5%25BB%25BA%25E7%25AB%258B+Statistics_%25E4%25BD%2586PK+%25E9%2582%2584%25E6%25B2%2592%25E6%259C%2589%25E7%2594%25A2%25E7%2594%259F+Statisitics.png" imageanchor="1"&gt;&lt;img border="0" height="220" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhavs33dO4MMIBh_lA6TS43WWvNVBT2WB9qfBykelnM6xsjc83Cr9wUhiEVca6u_mzWAvrzNeVMcU_idZMv_-q9Gb0u0e9zKpLBjTxlVvus3lvXtZw0b9kfWaDV1tzh50O3FBSLZBSShA0/s640/07_%25E8%2587%25AA%25E5%258B%2595%25E5%25BB%25BA%25E7%25AB%258B+Statistics_%25E4%25BD%2586PK+%25E9%2582%2584%25E6%25B2%2592%25E6%259C%2589%25E7%2594%25A2%25E7%2594%259F+Statisitics.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
08. 使用 SSMS 檢視 Index 與 Statistics。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;已經新增第 2 個 Statistics: _WA_Sys_00000003_226010D3&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;08_SSMS_Statistics&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj64vKXwDxeWNHZeS6oBkZXA4hRCs-6vmbQ-w6CZJBwVhS-6Asj21DXA_L9b_kWKYHLQcrJepY9EVPB4Kz6PuwfBWz-TVj1z84aUqOkMj2tAQd9KA7nO4glq4WT5nt4zUaahAsFxeSfQUY/s1600/08_SSMS_Statistics.png" imageanchor="1"&gt;&lt;img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj64vKXwDxeWNHZeS6oBkZXA4hRCs-6vmbQ-w6CZJBwVhS-6Asj21DXA_L9b_kWKYHLQcrJepY9EVPB4Kz6PuwfBWz-TVj1z84aUqOkMj2tAQd9KA7nO4glq4WT5nt4zUaahAsFxeSfQUY/s640/08_SSMS_Statistics.png" width="460" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
09. 檢視 Statistics 的 Details 頁籤。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;09_SSMS_Statistics_Details&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHgmy0ZA3m6MenIbie9RPoC2_8GWkq4_c-hOrN7BeehbAcqGFlleCRhCqdSQBC8sQvoz8-GhQEzt9oibEZgKNJtssxyYEkxyeYRLqu1ieegx0TNp6w5Q6niIjCzch9V9kPp-5wFvK0Eu0/s1600/09_SSMS_Statistics_Details.png" imageanchor="1"&gt;&lt;img border="0" height="228" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHgmy0ZA3m6MenIbie9RPoC2_8GWkq4_c-hOrN7BeehbAcqGFlleCRhCqdSQBC8sQvoz8-GhQEzt9oibEZgKNJtssxyYEkxyeYRLqu1ieegx0TNp6w5Q6niIjCzch9V9kPp-5wFvK0Eu0/s640/09_SSMS_Statistics_Details.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
10. 使用 DBCC SHOW_STATISTICS 與 WITH STAT_HEADER&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;DBCC SHOW_STATISTICS 可檢視指定 Index, Statistics, Column 的統計資訊。&lt;/li&gt;
&lt;li&gt;WITH STAT_HEADER，僅檢視 STAT_HEADER。&lt;/li&gt;
&lt;li&gt;與 dm_db_stats_properties 結果相同。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;10_DBCC SHOW_STATISTICS_WITH STAT_HEADER&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0MdSC_Qe0AUbWu2RsPg5BraCgxMV_7epmLsM48CduFcaJaIzZnM7LiTctsZysQFK4Oa4C8RfFsTBq7Q_SIfYkR3CvT0BfKEcGbIYBAeY0ZbCNYI0palP6k2ZBDGSgSDiyiaMQG4TENbs/s1600/10_DBCC+SHOW_STATISTICS_WITH+STAT_HEADER.png" imageanchor="1"&gt;&lt;img border="0" height="120" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0MdSC_Qe0AUbWu2RsPg5BraCgxMV_7epmLsM48CduFcaJaIzZnM7LiTctsZysQFK4Oa4C8RfFsTBq7Q_SIfYkR3CvT0BfKEcGbIYBAeY0ZbCNYI0palP6k2ZBDGSgSDiyiaMQG4TENbs/s640/10_DBCC+SHOW_STATISTICS_WITH+STAT_HEADER.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
11. 建立&amp;nbsp;Create NonClustered Index on [TransactionID]&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;11_Create NonClustered Index on TransactionID&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwnALbz1U2pvCysAjTQGCovHGruirpj5O_HUPVrYl9cFgXeB_8c5T5sq0lcU6ujQ-dt9nP9sNubC6XWz0PwfwL580gTa1iXmcuOZOOIyCzbY1VNbiRhsHwVSvc2bo-rYKgG-edVIAOtl8/s1600/11_Create+NonClustered+Index+on+TransactionID.png" imageanchor="1"&gt;&lt;img border="0" height="146" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwnALbz1U2pvCysAjTQGCovHGruirpj5O_HUPVrYl9cFgXeB_8c5T5sq0lcU6ujQ-dt9nP9sNubC6XWz0PwfwL580gTa1iXmcuOZOOIyCzbY1VNbiRhsHwVSvc2bo-rYKgG-edVIAOtl8/s640/11_Create+NonClustered+Index+on+TransactionID.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
12. 檢視 Statistics：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;產生第 3 個 statistics。&lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;建立 Index，系統自動建立對應的 Statistics: IX_Statistics_100K_TransactionID。&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
Statistics: IX_Statistics_100K_TransactionID&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Column: TransactionID&lt;/li&gt;
&lt;li&gt;rows: 100000&lt;/li&gt;
&lt;li&gt;rows_sampled:100000&lt;/li&gt;
&lt;li&gt;steps：2&lt;/li&gt;
&lt;li&gt;unfiltered_rows: 100000&lt;/li&gt;
&lt;li&gt;modification_counter: 0&lt;/li&gt;
&lt;li&gt;auto_created: 0&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
注意：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;PK_Statistics_100K_rid 尚未產生 Statistics&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;12_建立 Index_系統自動建立對應的 Statistics&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzc3Bkb9KoTVvDfO78G3zt1t56wiPyUYsnZGI6qd3H3f_VxfCbPMfOx_kybDiB03MJ8f2BaEvkzn9GrP_FIYqc04FSl1Pftlq7qxrOeawnJM4BlRMjiOrqXMfGzSbETIwSEtIyC2Ti9hs/s1600/12_%25E5%25BB%25BA%25E7%25AB%258B+Index_%25E7%25B3%25BB%25E7%25B5%25B1%25E8%2587%25AA%25E5%258B%2595%25E5%25BB%25BA%25E7%25AB%258B%25E5%25B0%258D%25E6%2587%2589%25E7%259A%2584+Statistics.png" imageanchor="1"&gt;&lt;img border="0" height="232" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzc3Bkb9KoTVvDfO78G3zt1t56wiPyUYsnZGI6qd3H3f_VxfCbPMfOx_kybDiB03MJ8f2BaEvkzn9GrP_FIYqc04FSl1Pftlq7qxrOeawnJM4BlRMjiOrqXMfGzSbETIwSEtIyC2Ti9hs/s640/12_%25E5%25BB%25BA%25E7%25AB%258B+Index_%25E7%25B3%25BB%25E7%25B5%25B1%25E8%2587%25AA%25E5%258B%2595%25E5%25BB%25BA%25E7%25AB%258B%25E5%25B0%258D%25E6%2587%2589%25E7%259A%2584+Statistics.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
13. 使用 SSMS 檢視 Index 與 Statistics。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;已經新增第 3 個 Statistics: IX_Statistics_100K_TransactionID&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;13_SSMS_Index_Statistics&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOVnEzap-hGLNzt2RylwwpS2-oXbsx5E-HWhEbccKJ6fCUiL72n2rnsIWNWZz3AL0fX5ZMWdTyPNdE1Cv5dMjQqjLU0KcjsDZOWfg64VPPnUa6m9O0puKjt7KzZHLVCMx0JBjaYP11Aw4/s1600/13_SSMS_Index_Statistics.png" imageanchor="1"&gt;&lt;img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOVnEzap-hGLNzt2RylwwpS2-oXbsx5E-HWhEbccKJ6fCUiL72n2rnsIWNWZz3AL0fX5ZMWdTyPNdE1Cv5dMjQqjLU0KcjsDZOWfg64VPPnUa6m9O0puKjt7KzZHLVCMx0JBjaYP11Aw4/s640/13_SSMS_Index_Statistics.png" width="629" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
14. 使用 SSMS 檢視 Statistics 的 Details 資訊。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;14_SSMS_Index_Statistics_Details&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4lV7EQZsMf-rMGdSM_EPEGYikFRig7piMA87VSnstlHiEf23bhJYEfyKGtFhSrSmuEbESvnNNUaeVolAtUPiVJ2Mwm9QGkNwhwIzkSSudbVDYw2e6hpg0QqQkhVIgE5tIfy3svqju2Sk/s1600/14_SSMS_Index_Statistics_Details.png" imageanchor="1"&gt;&lt;img border="0" height="216" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4lV7EQZsMf-rMGdSM_EPEGYikFRig7piMA87VSnstlHiEf23bhJYEfyKGtFhSrSmuEbESvnNNUaeVolAtUPiVJ2Mwm9QGkNwhwIzkSSudbVDYw2e6hpg0QqQkhVIgE5tIfy3svqju2Sk/s640/14_SSMS_Index_Statistics_Details.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
15. 使用 DBCC SHOW_STATISTICS 與 WITH STAT_HEADER&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;檢視 指定 Statistics: IX_Statistics_100K_TransactionID 的統計資訊&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;15_DBCC SHOW_STATISTICS_Index_Statistics&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7RGpssV5CWs9rrfFweQNnTrw6yDLR5iHeMjCetsg_OLZpaG9JG4KTxpLzcLKzz9OoAyqMEOkpf_U9FPADsYg5kPiEMHFGXoK15wV8XC1332fCbRpcKvXlnjx5qVeyi4bmD4sEYWAuIS0/s1600/15_DBCC+SHOW_STATISTICS_Index_Statistics.png" imageanchor="1"&gt;&lt;img border="0" height="128" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7RGpssV5CWs9rrfFweQNnTrw6yDLR5iHeMjCetsg_OLZpaG9JG4KTxpLzcLKzz9OoAyqMEOkpf_U9FPADsYg5kPiEMHFGXoK15wV8XC1332fCbRpcKvXlnjx5qVeyi4bmD4sEYWAuIS0/s640/15_DBCC+SHOW_STATISTICS_Index_Statistics.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="color: blue;"&gt;&lt;span style="font-size: large;"&gt;Statistics 尚未更新&amp;nbsp;，導致&amp;nbsp;Query Optimizer 無法選擇有效率的 Index&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;認識 AUTO_UPDATE_STATISTICS 自動更新統計資料&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
包含 SQL Server 2014 (12.x)，以及先前版本，會使用 變更資料列 的 百分比 作為 臨界值。&lt;br /&gt;
與資料表中的資料列數無關。&lt;br /&gt;
&lt;br /&gt;
臨界值是：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;若資料表基數在評估 統計資料 時為 500 或更小的數值，將會在每 500 次修改之後更新。&lt;/li&gt;
&lt;li&gt;若資料表基數在評估 統計資料 時為超過 500 的數值，將會在每 &lt;span style="color: blue;"&gt;&lt;b&gt;20% + 500&lt;/b&gt;&lt;/span&gt;&amp;nbsp;的修改次數之後更新。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
以本案例來看：&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Threshold is &lt;span style="color: blue;"&gt;20% + 500&lt;/span&gt;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;Count:&lt;span style="color: blue;"&gt; (100000 * 0.2) + 500 = 20500&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;資料表有 10 萬筆資料列，若要達到自動更新統計資訊的 臨界值&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;需要有 20,500 筆以上被異動。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
01. 本次案例，所使用的 SQL Query：&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;資料表有 10 萬筆，回傳 20,520 筆。&lt;/li&gt;
&lt;li&gt;Clustered Index Scan, Return 20,520 rows&lt;/li&gt;
&lt;li&gt;TransactionID &amp;lt; 120521&lt;/li&gt;
&lt;li&gt;Execution Plan: Missing Index&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;21_Clustered Index Scan_20520 rows&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhK_4c3JETYQFAYQLT2jGnoq60i_4s58NxgYSrJ5uFLuZ9R1Wn5INrwU4pONFfstQ6ezJCQs2r84mLoYiX7MSoB2ON-jdDWkD2nnYK7QQDABXB9J6-ZEv_0iW26feZ_kM_gBDh28vAXIg4/s1600/21_Clustered+Index+Scan_20520+rows.png" imageanchor="1"&gt;&lt;img border="0" height="607" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhK_4c3JETYQFAYQLT2jGnoq60i_4s58NxgYSrJ5uFLuZ9R1Wn5INrwU4pONFfstQ6ezJCQs2r84mLoYiX7MSoB2ON-jdDWkD2nnYK7QQDABXB9J6-ZEv_0iW26feZ_kM_gBDh28vAXIg4/s640/21_Clustered+Index+Scan_20520+rows.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 有 Missing Index&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;22_Clustered Index Scan_20520 rows_Missing_Index&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK1Lu-NIHTogE1eLQc11KRT9LzC2h5ZMuMnUNaKfjsRNFvmeOlATCzBB1bA91dBOkeEnmb__qVlVHDbd_8o29a2HxX4zDBCadOvLpbYqB-nkFEGwgKA_dkFoIwwHMiNpokfByUM5Ol7qo/s1600/22_Clustered+Index+Scan_20520+rows_Missing_Index.png" imageanchor="1"&gt;&lt;img border="0" height="226" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK1Lu-NIHTogE1eLQc11KRT9LzC2h5ZMuMnUNaKfjsRNFvmeOlATCzBB1bA91dBOkeEnmb__qVlVHDbd_8o29a2HxX4zDBCadOvLpbYqB-nkFEGwgKA_dkFoIwwHMiNpokfByUM5Ol7qo/s640/22_Clustered+Index+Scan_20520+rows_Missing_Index.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
檢視 Execution Plan&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Cluster Index Scan&lt;/li&gt;
&lt;li&gt;Reads: 1,289&lt;/li&gt;
&lt;li&gt;Est Rows: 20,520&lt;/li&gt;
&lt;li&gt;Actual Rows: 20,520&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure 41_Execution_Plan&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwpYBG0zep3ngSJM-VjGvhfGs4hHzUbbzriStHnNdk0epNeO8twn5g43svP5SrYG4xvBRNmFL_Z5D0rBDsR_m4tzSR6Zljr3NhVxt7FL0IXl_pFUvJ3BFPm_Bd5GI2DmvxKmTEB2GxgEs/s1600/41_Execution_Plan.png" imageanchor="1"&gt;&lt;img border="0" height="198" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwpYBG0zep3ngSJM-VjGvhfGs4hHzUbbzriStHnNdk0epNeO8twn5g43svP5SrYG4xvBRNmFL_Z5D0rBDsR_m4tzSR6Zljr3NhVxt7FL0IXl_pFUvJ3BFPm_Bd5GI2DmvxKmTEB2GxgEs/s640/41_Execution_Plan.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 刪除資料&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;刪除 20,300 筆。&lt;/li&gt;
&lt;li&gt;但仍 未達到 更新 Statistics 的 threshold(臨界值)&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;ul&gt;&lt;ul&gt;
&lt;li&gt;Threshold is 20% + 500，需要超過 20,500 筆。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;23_Delete 20300 rows&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhr2YghSAxIxQHQyHISE1Jy9TITPCplfB0e5sdEiNIgaL9ZLmR7teP-Fcxe39Bj8RshEZ-tQp6mn37NsA5Wgcr6lsyr0_lBJUk7n0dJBTUiu26JX0JzAj_lav0V4Jf6-Ny4g8rJP3id_GY/s1600/23_Delete+20300+rows.png" imageanchor="1"&gt;&lt;img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhr2YghSAxIxQHQyHISE1Jy9TITPCplfB0e5sdEiNIgaL9ZLmR7teP-Fcxe39Bj8RshEZ-tQp6mn37NsA5Wgcr6lsyr0_lBJUk7n0dJBTUiu26JX0JzAj_lav0V4Jf6-Ny4g8rJP3id_GY/s640/23_Delete+20300+rows.png" width="586" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
04. 執行 SQL Query，僅回傳 1 row。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;24_Query_1_row&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-4Fd-ORPyOzPdgLcNbHRsjq1QgbRfn31djbLgHN_i23MBisWLG69YLE5iBW-aPcYIhd-i26fgDthTOmsuaaTm7mm9VPOz6qjkNfFfMuujI74Sw2T1qIcNXQ70dq2CeUXfVU_IWvS-4ow/s1600/24_Query_1_row.png" imageanchor="1"&gt;&lt;img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-4Fd-ORPyOzPdgLcNbHRsjq1QgbRfn31djbLgHN_i23MBisWLG69YLE5iBW-aPcYIhd-i26fgDthTOmsuaaTm7mm9VPOz6qjkNfFfMuujI74Sw2T1qIcNXQ70dq2CeUXfVU_IWvS-4ow/s640/24_Query_1_row.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
05. 檢視 Statistics：&lt;br /&gt;
&lt;br /&gt;
Under Threshold (未達 臨界值)&lt;br /&gt;
&lt;br /&gt;
(1) Statistics:IX_Statistics_100K_TransactionID &lt;span style="color: red;"&gt;保持不變&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;累計： modification_counter: &lt;span style="color: red;"&gt;20300&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Total: 79,700 rows, (SELECT 100000 - 20300 -- 79700)&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
(2) Statistics:PK_Statistics_100K_rid 已經自動產生&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Column: rid&lt;/li&gt;
&lt;li&gt;rows: 100000&lt;/li&gt;
&lt;li&gt;rows_sampled:87284&lt;/li&gt;
&lt;li&gt;steps：37&lt;/li&gt;
&lt;li&gt;unfiltered_rows: 100000&lt;/li&gt;
&lt;li&gt;modification_counter: &lt;span style="color: red;"&gt;20300&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;auto_created: 0&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;25_Statistics PK_Statistics_100K_rid 已經自動產生_未達 臨界值_保持不變&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoTjpqcKIPSDbSPvdJamDIE0iv3riJ71SISE9YQXmXfLqmawGCe6w5aUT9ZmX0rGqWbfyOP6KvNrbIWwyaqbBQ2sIqv5rFhWq3euUfdVFvWPRVprHsp25MKbN7lDDfA2bbO3_S1QXXcBc/s1600/25_Statistics+PK_Statistics_100K_rid+%25E5%25B7%25B2%25E7%25B6%2593%25E8%2587%25AA%25E5%258B%2595%25E7%2594%25A2%25E7%2594%259F_%25E6%259C%25AA%25E9%2581%2594+%25E8%2587%25A8%25E7%2595%258C%25E5%2580%25BC_%25E4%25BF%259D%25E6%258C%2581%25E4%25B8%258D%25E8%25AE%258A.png" imageanchor="1"&gt;&lt;img border="0" height="72" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoTjpqcKIPSDbSPvdJamDIE0iv3riJ71SISE9YQXmXfLqmawGCe6w5aUT9ZmX0rGqWbfyOP6KvNrbIWwyaqbBQ2sIqv5rFhWq3euUfdVFvWPRVprHsp25MKbN7lDDfA2bbO3_S1QXXcBc/s640/25_Statistics+PK_Statistics_100K_rid+%25E5%25B7%25B2%25E7%25B6%2593%25E8%2587%25AA%25E5%258B%2595%25E7%2594%25A2%25E7%2594%259F_%25E6%259C%25AA%25E9%2581%2594+%25E8%2587%25A8%25E7%2595%258C%25E5%2580%25BC_%25E4%25BF%259D%25E6%258C%2581%25E4%25B8%258D%25E8%25AE%258A.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
06. 再刪除 10 rows。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;再刪除 10 rows。&lt;/li&gt;
&lt;li&gt;累計刪除: 20300 + 10 = 20,310 筆。&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;但 Threshold is 20% + 500，需要超過 20,500 筆。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;26_再刪除 10 rows_Under Threshold_未達 臨界值&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIL585LOHsNxIcZqB2uX6jAPZE_UDUvCglptpJKHxpfi1mU_NDg1SDL-kBKdL1bg6Yq8nSkxBGMiluO8lHRJitThEFV0j6EfGXovmyO2e5tgSbfdKxePZQLqA0rMTkkPZfo2lE0GaPyDU/s1600/26_%25E5%2586%258D%25E5%2588%25AA%25E9%2599%25A4+10+rows_Under+Threshold_%25E6%259C%25AA%25E9%2581%2594+%25E8%2587%25A8%25E7%2595%258C%25E5%2580%25BC.png" imageanchor="1"&gt;&lt;img border="0" height="548" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIL585LOHsNxIcZqB2uX6jAPZE_UDUvCglptpJKHxpfi1mU_NDg1SDL-kBKdL1bg6Yq8nSkxBGMiluO8lHRJitThEFV0j6EfGXovmyO2e5tgSbfdKxePZQLqA0rMTkkPZfo2lE0GaPyDU/s640/26_%25E5%2586%258D%25E5%2588%25AA%25E9%2599%25A4+10+rows_Under+Threshold_%25E6%259C%25AA%25E9%2581%2594+%25E8%2587%25A8%25E7%2595%258C%25E5%2580%25BC.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
07. 檢視 Statistics：&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;仍是 Under Threshold (未達 臨界值)，沒有更新 Statistics&lt;/li&gt;
&lt;li&gt;累計刪除: 20300 + 10 = &lt;span style="color: red;"&gt;20,310&lt;/span&gt; 筆。&lt;/li&gt;
&lt;li&gt;Total: 79,690 rows, (SELECT 100000 - 20300 - 10 -- 79690)&lt;/li&gt;
&lt;li&gt;modification_counter:&amp;nbsp;&lt;span style="color: red;"&gt;20310&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;但 Threshold is 20% + 500，需要超過 &lt;span style="color: blue;"&gt;20,500 &lt;/span&gt;筆。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;27_modification_counter_未達 臨界值&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguNUYnk_foHbVlw7P5u1mGliB1lAFC7FpGsXHaWLmoe0Hb5Dx_TrsM3uSHzeq3AeJb_yaIUCJFIY8M7PanPh_jxUKAZAsjZIdSNQW2GHS_i1EVD1UtltH9k9FGledFbM-1pfO8vylNylI/s1600/27_modification_counter_%25E6%259C%25AA%25E9%2581%2594+%25E8%2587%25A8%25E7%2595%258C%25E5%2580%25BC.png" imageanchor="1"&gt;&lt;img border="0" height="56" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguNUYnk_foHbVlw7P5u1mGliB1lAFC7FpGsXHaWLmoe0Hb5Dx_TrsM3uSHzeq3AeJb_yaIUCJFIY8M7PanPh_jxUKAZAsjZIdSNQW2GHS_i1EVD1UtltH9k9FGledFbM-1pfO8vylNylI/s640/27_modification_counter_%25E6%259C%25AA%25E9%2581%2594+%25E8%2587%25A8%25E7%2595%258C%25E5%2580%25BC.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
08. 檢視 資料表&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;剩下 79,690 rows。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;28_Table_剩下_79690&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigFpyNMUEe6uJn5wGT4B1uChkd80bHvTGhd5uQOOj4b7plxE0iGPOGWHKaC6-zTN8HNAZg9D6QBiWmKsi3LosGYHc6JnEc2zr0vTwpFwjHZeCLu0N_I3K7YganWepPH_Lkr7YYpZBzPHc/s1600/28_Table_%25E5%2589%25A9%25E4%25B8%258B_79690.png" imageanchor="1"&gt;&lt;img border="0" height="220" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigFpyNMUEe6uJn5wGT4B1uChkd80bHvTGhd5uQOOj4b7plxE0iGPOGWHKaC6-zTN8HNAZg9D6QBiWmKsi3LosGYHc6JnEc2zr0vTwpFwjHZeCLu0N_I3K7YganWepPH_Lkr7YYpZBzPHc/s640/28_Table_%25E5%2589%25A9%25E4%25B8%258B_79690.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
09. 執行先前範例 SQL Query:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;資料量已大幅刪除，回傳資料量減少，推論可以改用 Index Seek&lt;/li&gt;
&lt;li&gt;但卻仍是使用 Clustered Index &lt;span style="color: red;"&gt;Scan&lt;/span&gt;, 僅 Return 210 rows&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Missing Index&lt;/li&gt;
&lt;li&gt;回傳筆數，由 20,520 減少至 &lt;span style="color: blue;"&gt;210 &lt;/span&gt;rows&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
因為 Statistics 尚未更新，Query Optimizer 仍選擇原先的 Index。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;29_仍是使用 Clustered Index Scan&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAIhOaqCguhenXTnn6PXkpulJErTeoMQlzYj-_M0WrngfgF8a_3_e_0Gi7L4Bahv1UL4oRu4kH9Xg5Eb-HjeR4VOKrGaSUXJeYGXrrTAzjI9XjGY_DJR1lPRz_HKZWSQsaWWaVfO6JHKU/s1600/29_%25E4%25BB%258D%25E6%2598%25AF%25E4%25BD%25BF%25E7%2594%25A8+Clustered+Index+Scan.png" imageanchor="1"&gt;&lt;img border="0" height="292" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAIhOaqCguhenXTnn6PXkpulJErTeoMQlzYj-_M0WrngfgF8a_3_e_0Gi7L4Bahv1UL4oRu4kH9Xg5Eb-HjeR4VOKrGaSUXJeYGXrrTAzjI9XjGY_DJR1lPRz_HKZWSQsaWWaVfO6JHKU/s640/29_%25E4%25BB%258D%25E6%2598%25AF%25E4%25BD%25BF%25E7%2594%25A8+Clustered+Index+Scan.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
檢視 Execution Plan&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Cluster Index Scan&lt;/li&gt;
&lt;li&gt;Reads: 1,030&lt;/li&gt;
&lt;li&gt;Est Rows: &lt;span style="color: blue;"&gt;20,520&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Actual Rows: &lt;span style="color: red;"&gt;210&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
預估有 20,520 筆，但實際卻僅有 210 筆。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;42_Execution_Plan_Delete_尚未更新_Statistics&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgH-XiR5rYxVkYi6hMR8iYLerHobPsAATpHc-WTvVh2jtDqcn_XtmYwzoWNBEV9spiWoDsSzRpnNFY6muVk9fz3lrZbTsSdHUbqutDDBPAsFz8v8q3Vm5cSXMCS1GTcQ0Asrm6PApQNcV8/s1600/42_Execution_Plan_Delete_%25E5%25B0%259A%25E6%259C%25AA%25E6%259B%25B4%25E6%2596%25B0_Statistics.png" imageanchor="1"&gt;&lt;img border="0" height="206" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgH-XiR5rYxVkYi6hMR8iYLerHobPsAATpHc-WTvVh2jtDqcn_XtmYwzoWNBEV9spiWoDsSzRpnNFY6muVk9fz3lrZbTsSdHUbqutDDBPAsFz8v8q3Vm5cSXMCS1GTcQ0Asrm6PApQNcV8/s640/42_Execution_Plan_Delete_%25E5%25B0%259A%25E6%259C%25AA%25E6%259B%25B4%25E6%2596%25B0_Statistics.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;異動資料，超過更新 Statistics 的 threshold&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
01. 再刪除 200 rows&lt;br /&gt;
&lt;br /&gt;
Over Threshold (超過 臨界值)&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;再刪除 200 rows，Over Threshold (超過 臨界值)&lt;/li&gt;
&lt;li&gt;TransactionID &amp;lt; 120511&lt;/li&gt;
&lt;li&gt;累計： 已經刪除 &lt;span style="color: red;"&gt;20,510&lt;/span&gt; rows&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;(20,300 + 10 + 200)&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;Threshold is 20% + 500，需要超過&amp;nbsp;&lt;span style="color: blue;"&gt;20,500&amp;nbsp;&lt;/span&gt;筆。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;31_再刪除 200 rows_Over Threshold (超過 臨界值)&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeU0jsdSc3iEHcda_7UXG-x_h3nN5twepKi574mEAqxpj_Ki91PTKv9o0Vqa8mKRA4yP-P9zqDezJyOd6WKT44DLy3zDjUu1PtI2kuTzJdZPwNHwad0OiCXtjTwFexhwp_N5wIS_wMytg/s1600/31_%25E5%2586%258D%25E5%2588%25AA%25E9%2599%25A4+200+rows_Over+Threshold+%2528%25E8%25B6%2585%25E9%2581%258E+%25E8%2587%25A8%25E7%2595%258C%25E5%2580%25BC%2529.png" imageanchor="1"&gt;&lt;img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeU0jsdSc3iEHcda_7UXG-x_h3nN5twepKi574mEAqxpj_Ki91PTKv9o0Vqa8mKRA4yP-P9zqDezJyOd6WKT44DLy3zDjUu1PtI2kuTzJdZPwNHwad0OiCXtjTwFexhwp_N5wIS_wMytg/s640/31_%25E5%2586%258D%25E5%2588%25AA%25E9%2599%25A4+200+rows_Over+Threshold+%2528%25E8%25B6%2585%25E9%2581%258E+%25E8%2587%25A8%25E7%2595%258C%25E5%2580%25BC%2529.png" width="586" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 檢視 Statistics：&lt;br /&gt;
&lt;br /&gt;
超過 臨界值，但 Statistics 仍未改變 !&lt;br /&gt;
&lt;br /&gt;
Statistics: IX_Statistics_100K_TransactionID&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Column: TransactionID&lt;/li&gt;
&lt;li&gt;rows: 100000&lt;/li&gt;
&lt;li&gt;rows_sampled:100000&lt;/li&gt;
&lt;li&gt;steps：2&lt;/li&gt;
&lt;li&gt;unfiltered_rows: 100000&lt;/li&gt;
&lt;li&gt;modification_counter: &lt;span style="color: blue;"&gt;20510&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;auto_created: 0&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;32_超過 臨界值，但 Statistics 仍未改變&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiD1gLOUWad5fm-EykXbZNc6kS_MIPx8CR5W6Um4zqf7NAoWHk5O3SavV-gbN70O6JX8iIbZkjicxmHctc5aKw3usvqnQd6gRJ9D4EptNgMgN2VTPBKN2r-Gti1_tx2tGK3YiyGIuBnKss/s1600/32_%25E8%25B6%2585%25E9%2581%258E+%25E8%2587%25A8%25E7%2595%258C%25E5%2580%25BC%25EF%25BC%258C%25E4%25BD%2586+Statistics+%25E4%25BB%258D%25E6%259C%25AA%25E6%2594%25B9%25E8%25AE%258A.png" imageanchor="1"&gt;&lt;img border="0" height="100" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiD1gLOUWad5fm-EykXbZNc6kS_MIPx8CR5W6Um4zqf7NAoWHk5O3SavV-gbN70O6JX8iIbZkjicxmHctc5aKw3usvqnQd6gRJ9D4EptNgMgN2VTPBKN2r-Gti1_tx2tGK3YiyGIuBnKss/s640/32_%25E8%25B6%2585%25E9%2581%258E+%25E8%2587%25A8%25E7%2595%258C%25E5%2580%25BC%25EF%25BC%258C%25E4%25BD%2586+Statistics+%25E4%25BB%258D%25E6%259C%25AA%25E6%2594%25B9%25E8%25AE%258A.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 再度執行 SQL Query&lt;br /&gt;
&lt;br /&gt;
AUTO_UPDATE_STATISTICS&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;開啟自動更新統計資料選項 AUTO_UPDATE_STATISTICS 時，Query Optimizer 會判斷 statistics 何時過期，然後在查詢使用 statistics 時加以更新。&lt;/li&gt;
&lt;li&gt;在編譯查詢及執行快取 query plan 之前，Query Optimizer 會檢查是否有過期的 statistics 。&amp;nbsp;&lt;/li&gt;
&lt;li&gt;在編譯查詢之前，Query Optimizer 會使用查詢述詞中的資料行、資料表和索引檢視表來判斷哪些 statistics 可能已過期。&amp;nbsp;&lt;/li&gt;
&lt;li&gt;在執行快取 query plan 之前， Database Engine 會確認 query plan 是否參考最新的 statistics。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
換言之:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;statistics 過期後，要等到下次執行 Query(SIUD)， 查詢 statistics 時，一併更新 statistics。&lt;/li&gt;
&lt;li&gt;如果 statistics 已過期，Query Optimizer 就會先等候並執行更新 statistics，然後再 compile 並執行查詢。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;33_何時更新 statistics_ 下次執行 Query(SIUD)&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs_cNGWGQ4cfbH9Erl69AGabaSWxDhbapEWunCBL5oRq4WXl4eLrlfXPFIHSNNI1lMS_xYtgbSnWEZeLwZfjVLvHXbTcoZ-Q9oWORmtlk-HsTIyTBD2XJfbv28LxmAFDpHzJiJjWafmkU/s1600/33_%25E4%25BD%2595%25E6%2599%2582%25E6%259B%25B4%25E6%2596%25B0+statistics_+%25E4%25B8%258B%25E6%25AC%25A1%25E5%259F%25B7%25E8%25A1%258C+Query%2528SIUD%2529.png" imageanchor="1"&gt;&lt;img border="0" height="278" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs_cNGWGQ4cfbH9Erl69AGabaSWxDhbapEWunCBL5oRq4WXl4eLrlfXPFIHSNNI1lMS_xYtgbSnWEZeLwZfjVLvHXbTcoZ-Q9oWORmtlk-HsTIyTBD2XJfbv28LxmAFDpHzJiJjWafmkU/s640/33_%25E4%25BD%2595%25E6%2599%2582%25E6%259B%25B4%25E6%2596%25B0+statistics_+%25E4%25B8%258B%25E6%25AC%25A1%25E5%259F%25B7%25E8%25A1%258C+Query%2528SIUD%2529.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
檢視 Execution Plan&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;Index Seek&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Reads:&amp;nbsp;&lt;span style="color: blue;"&gt;33&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Est Rows:&amp;nbsp;&lt;span style="color: blue;"&gt;10&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Actual Rows:&amp;nbsp;&lt;span style="color: blue;"&gt;10&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;43_Execution_Plan_已更新_Statistics&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQdgAJDFtxEX-zOVt-NG0fTrRR13K3WuRq0juzBGt5qlhDBWXWcdR986zqZDg-HTmWYpA3yH3ua5QCTKvxOkJiKFQZRevugNnrHSA5HvCX0ISZAhAlo7Gq146sfXSRbBro2MAtHQo5RVs/s1600/43_Execution_Plan_%25E5%25B7%25B2%25E6%259B%25B4%25E6%2596%25B0_Statistics.png" imageanchor="1"&gt;&lt;img border="0" height="198" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQdgAJDFtxEX-zOVt-NG0fTrRR13K3WuRq0juzBGt5qlhDBWXWcdR986zqZDg-HTmWYpA3yH3ua5QCTKvxOkJiKFQZRevugNnrHSA5HvCX0ISZAhAlo7Gq146sfXSRbBro2MAtHQo5RVs/s640/43_Execution_Plan_%25E5%25B7%25B2%25E6%259B%25B4%25E6%2596%25B0_Statistics.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
04. 檢視 Statistics&lt;br /&gt;
&lt;br /&gt;
Statistics 已經更新&lt;br /&gt;
modification_counter:&amp;nbsp;&lt;span style="color: blue;"&gt;0&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
(1)　Statistics: IX_Statistics_100K_TransactionID&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Column: TransactionID&lt;/li&gt;
&lt;li&gt;rows: 79490&lt;/li&gt;
&lt;li&gt;rows_sampled:79490&lt;/li&gt;
&lt;li&gt;steps：3&lt;/li&gt;
&lt;li&gt;unfiltered_rows: 79490&lt;/li&gt;
&lt;li&gt;modification_counter:&amp;nbsp;&lt;span style="color: blue;"&gt;0&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;auto_created: 0&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
(2)　Statistics: PK_Statistics_100K_rid&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Column: rid&lt;/li&gt;
&lt;li&gt;rows: 79490&lt;/li&gt;
&lt;li&gt;rows_sampled:79490&lt;/li&gt;
&lt;li&gt;steps：3&lt;/li&gt;
&lt;li&gt;unfiltered_rows: 79490&lt;/li&gt;
&lt;li&gt;modification_counter:&amp;nbsp;&lt;span style="color: blue;"&gt;0&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;auto_created: 0&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
(3) _WA_Sys_00000003_226010D3&amp;nbsp;&lt;span style="color: red;"&gt;仍是未更新&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style="color: red;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
-- figure&amp;nbsp;34_Statistics_已經更新&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAbdccUm0q-oCf12xr_t3gjAoICikFDonOzt1kOU4moNS-dzXUtuy4ZLxaMeaCjQADwMCmecw4wvTAfKoMudaDHuM1eL597dVmeXnHdjFEb2bXpqbsKsCvFeON-7SgUt9L7d89Ag2euIk/s1600/34_Statistics_%25E5%25B7%25B2%25E7%25B6%2593%25E6%259B%25B4%25E6%2596%25B0.png" imageanchor="1"&gt;&lt;img border="0" height="66" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAbdccUm0q-oCf12xr_t3gjAoICikFDonOzt1kOU4moNS-dzXUtuy4ZLxaMeaCjQADwMCmecw4wvTAfKoMudaDHuM1eL597dVmeXnHdjFEb2bXpqbsKsCvFeON-7SgUt9L7d89Ag2euIk/s640/34_Statistics_%25E5%25B7%25B2%25E7%25B6%2593%25E6%259B%25B4%25E6%2596%25B0.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
05. 使用 DBCC SHOW_STATISTICS 與 WITH STAT_HEADER&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;檢視 指定 Statistics: IX_Statistics_100K_TransactionID 的統計資訊&lt;/li&gt;
&lt;/ul&gt;
-- figure&amp;nbsp;35_DBCC SHOW_STATISTICS_Statistics_已經更新&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiV3nCWNCFDx0iDAtvEyIEdL7D1fSp8UyhjajJdeOBv4AAaIOQcxcS2ec4Ip7UTX9T0n149o6YAMOJugsVE_nqBjms6I0wGGofFhHNVIN4rl7b4yjOMlboEN27sWrAxf2zpfA1ugwMpD-g/s1600/35_DBCC+SHOW_STATISTICS_Statistics_%25E5%25B7%25B2%25E7%25B6%2593%25E6%259B%25B4%25E6%2596%25B0.png" imageanchor="1"&gt;&lt;img border="0" height="50" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiV3nCWNCFDx0iDAtvEyIEdL7D1fSp8UyhjajJdeOBv4AAaIOQcxcS2ec4Ip7UTX9T0n149o6YAMOJugsVE_nqBjms6I0wGGofFhHNVIN4rl7b4yjOMlboEN27sWrAxf2zpfA1ugwMpD-g/s640/35_DBCC+SHOW_STATISTICS_Statistics_%25E5%25B7%25B2%25E7%25B6%2593%25E6%259B%25B4%25E6%2596%25B0.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;Statistics 更新前後的比較&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;table border="1" cellpadding="1" cellspacing="1"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;Before&lt;/td&gt;&lt;td&gt;After&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Index&lt;/td&gt;&lt;td&gt;Clustered Index&amp;nbsp;&lt;span style="color: red;"&gt;Scan&lt;/span&gt;&lt;/td&gt;&lt;td&gt;Index&amp;nbsp;&lt;span style="color: blue;"&gt;Seek&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;&lt;span style="color: red;"&gt;1,030&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="color: blue;"&gt;33&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Est Rows&lt;/td&gt;&lt;td&gt;20,520&lt;/td&gt;&lt;td&gt;10&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
更新過的 Statistics，能夠反映實際的資料特性，幫助 Query Optimizer 選擇合適的 Index。&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;若以 Read IO 來看，更新 Statistics 後，幫助 Query Optimizer 選擇合適的 Index&lt;/li&gt;
&lt;li&gt;效能提升：96.8 %。&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
SELECT ABS(33-1030)/1030.0 * 100 -- 96.796100&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Sample Code&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
20181011_Use Autostat (AUTO_UPDATE_STATISTICS)&lt;br /&gt;
&lt;a href="https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing"&gt;https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Reference&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
AUTO_UPDATE_STATISTICS Option&lt;br /&gt;
&lt;a href="https://docs.microsoft.com/zh-tw/sql/relational-databases/statistics/statistics?view=sql-server-2017"&gt;https://docs.microsoft.com/zh-tw/sql/relational-databases/statistics/statistics?view=sql-server-2017&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Controlling Autostat (AUTO_UPDATE_STATISTICS) behavior in SQL Server&lt;br /&gt;
&lt;a href="https://support.microsoft.com/en-us/help/2754171/controlling-autostat-auto-update-statistics-behavior-in-sql-server"&gt;https://support.microsoft.com/en-us/help/2754171/controlling-autostat-auto-update-statistics-behavior-in-sql-server&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Changes to automatic update statistics in SQL Server – traceflag 2371&lt;br /&gt;
&lt;a href="https://blogs.msdn.microsoft.com/saponsqlserver/2011/09/07/changes-to-automatic-update-statistics-in-sql-server-traceflag-2371/"&gt;https://blogs.msdn.microsoft.com/saponsqlserver/2011/09/07/changes-to-automatic-update-statistics-in-sql-server-traceflag-2371/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Default auto statistics update threshold change for SQL Server 2016&lt;br /&gt;
&lt;a href="https://blogs.msdn.microsoft.com/psssql/2016/10/04/default-auto-statistics-update-threshold-change-for-sql-server-2016/"&gt;https://blogs.msdn.microsoft.com/psssql/2016/10/04/default-auto-statistics-update-threshold-change-for-sql-server-2016/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Statistics Used by the Query Optimizer in Microsoft SQL Server 2008&lt;br /&gt;
&lt;a href="https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2008/dd535534(v=sql.100)"&gt;https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2008/dd535534(v=sql.100)&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Statistics Used by the Query Optimizer in Microsoft SQL Server 2005&lt;br /&gt;
&lt;a href="https://technet.microsoft.com/en-us/library/cc966419.aspx"&gt;https://technet.microsoft.com/en-us/library/cc966419.aspx&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
How Statistics in SQL Server determines performance&lt;br /&gt;
&lt;a href="https://blogs.msdn.microsoft.com/ggaurav/2015/04/10/how-statistics-in-sql-server-determines-performance/"&gt;https://blogs.msdn.microsoft.com/ggaurav/2015/04/10/how-statistics-in-sql-server-determines-performance/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Batch Compilation, Recompilation, and Plan Caching Issues in SQL Server 2005&lt;br /&gt;
Recompilation threshold (RT)&lt;br /&gt;
&lt;a href="https://technet.microsoft.com/en-us/library/cc966425.aspx"&gt;https://technet.microsoft.com/en-us/library/cc966425.aspx&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Statistical maintenance functionality (AutoStats) in SQL Server&lt;br /&gt;
"change threshold"&lt;br /&gt;
&lt;a href="https://support.microsoft.com/en-us/help/195565/statistical-maintenance-functionality-autostats-in-sql-server"&gt;https://support.microsoft.com/en-us/help/195565/statistical-maintenance-functionality-autostats-in-sql-server&lt;/a&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</description><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpC5jZzHNvjMWKVYN58K5ppgtnLXUDoFZwTAgBxi10giii_Y2ezL3lzpLVeqFdf5YVrV0zg4uALO_astMi-yUyAerRpZhJYrdtpPNbZU9REOHTJh2OC_4jpTlWJPerZ7eg4JeBh1ouY4M/s72-c/61_dm_db_stats_properties.png" width="72"/><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><title>Dynamic SQL: Pass dynamic TABLE name variable, 動態傳遞 資料表名稱 變數</title><link>http://sharedderrick.blogspot.com/2018/09/dynamic-sql-spexecutesql-pass-dynamic.html</link><category>Performance Tuning</category><category>SQL Server</category><author>noreply@blogger.com (DerrickLaLa)</author><pubDate>Mon, 17 Sep 2018 20:15:00 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1420955872914622499.post-7509930228603091101</guid><description>&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
&lt;span style="color: red; font-size: large;"&gt;&lt;b&gt;消失的 Execution Plan&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
當使用 Dynamic SQL 動態傳遞&amp;nbsp; TABLE name(資料表名稱) 變數&lt;br /&gt;
&lt;br /&gt;
無論是使用 sp_executesql 或 EXEC，都要等到 執行階段，動態傳入資料表名稱 後，Query Optimizer 方能依據傳入的資料表資訊，分析 SQL 陳述式，判斷出取得所需資料的最有效方式。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
影響&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Display Estimated Execution Plan 無法正確顯示。&lt;/li&gt;
&lt;li&gt;Plan Cache 無法直接觀察。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTd4-1NUb4IM1fF1Xjrz3QcCR0945EU8biNLGeBa6P_ZhYLHXn_8JSowp2X0F4_FbIo4g6kNWluVySxMtmd34NMv4weJPxVKiPMJ0uAFN2idfkDRSo4pV0B-KhUoIfaN2l262tGMmLBJg/s1600/03_Display+Estimated+Exectution+Plan.png" imageanchor="1"&gt;&lt;img border="0" height="516" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTd4-1NUb4IM1fF1Xjrz3QcCR0945EU8biNLGeBa6P_ZhYLHXn_8JSowp2X0F4_FbIo4g6kNWluVySxMtmd34NMv4weJPxVKiPMJ0uAFN2idfkDRSo4pV0B-KhUoIfaN2l262tGMmLBJg/s640/03_Display+Estimated+Exectution+Plan.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;看不到 實際執行的 Execution Plan!&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhn__mxqKXB0XwkCSmYkpCAyeV8EZcS4dviwVKNWzzyF04-jaw8kqChlHxu2jRZZzkBgFrZljK7vg9DItgGHkouy3-Bhrca4QjK1QCo7Jl3pw8Zuy-HUoCKo10DG1_uk3Cc84_voMQ7jaI/s1600/09_6.png" imageanchor="1"&gt;&lt;img border="0" height="264" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhn__mxqKXB0XwkCSmYkpCAyeV8EZcS4dviwVKNWzzyF04-jaw8kqChlHxu2jRZZzkBgFrZljK7vg9DItgGHkouy3-Bhrca4QjK1QCo7Jl3pw8Zuy-HUoCKo10DG1_uk3Cc84_voMQ7jaI/s640/09_6.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Dynamic SQL: sp_executesql,&amp;nbsp; Pass dynamic TABLE name variable,&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;動態傳遞 資料表名稱 變數&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
01.&amp;nbsp;建立使用 Dynamic SQL: sp_executesql 動態傳遞 資料表變數 的 Stored Procedure。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;@tsql&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;需要執行的 SQL 陳述式或批次，必須使用 Unicode 字串。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;@Parms&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;&lt;ul&gt;
&lt;li&gt;N'@TransactionDate datetime'，此為參數定義的 Unicode 字串。，由&amp;nbsp;參數名稱 和 資料類型 組成。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
使用 QUOTENAME()&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;附加傳回 [] 分隔符號，以便讓 輸入字串 成為有效的&amp;nbsp; [SQL Server] 分隔識別碼。&lt;/li&gt;
&lt;li&gt;限制為 128 個 Unicode&amp;nbsp; 字元。&lt;/li&gt;
&lt;li&gt;用於處理 SQL Injection(資料隱碼) 問題， 驗證 Dynamic SQL 使用的所有變數都已正確處理。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;01_Proc_pr_DynamicTable&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgemYkfjQSPzZx9zfPUvd-Yc1fwvUIuI3P5h-Rtt_vc2JVk_Dy2DGvY_5if7bUo6qGF4iEvgAPZYEa9NioAdj_5rbEQD9p1wH5pOvkWIDwU-shZ7fgxvGa3QgblVzp0wUQtGwsOxk_fuTA/s1600/01_Proc_pr_DynamicTable.png" imageanchor="1"&gt;&lt;img border="0" height="232" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgemYkfjQSPzZx9zfPUvd-Yc1fwvUIuI3P5h-Rtt_vc2JVk_Dy2DGvY_5if7bUo6qGF4iEvgAPZYEa9NioAdj_5rbEQD9p1wH5pOvkWIDwU-shZ7fgxvGa3QgblVzp0wUQtGwsOxk_fuTA/s640/01_Proc_pr_DynamicTable.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 點選 &lt;b&gt;&lt;span style="color: blue;"&gt;Display Estimated Execution Plan&lt;/span&gt;&lt;/b&gt;，嘗試檢視 Execution Plan。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;檢視 使用 Dynamic SQL: sp_executesql 動態傳遞 資料表名稱 變數 的 Stored Procedure。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;02_Display Estimated Execution Plan&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikqqTTj3uU-K-rcdNja4lYXlCnYK5W_h-dmM-a-2jJvsv-MY36xN3B7QXsVULbug86ibf-cjqRGTZ5EJszGmkeqCqDld4vq1ILY2x0ce_xMnh-OitZAF8IknOBjybTbqNCrvLvwX8qFHM/s1600/02_Display+Estimated+Exectution+Plan.png" imageanchor="1"&gt;&lt;img border="0" height="224" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikqqTTj3uU-K-rcdNja4lYXlCnYK5W_h-dmM-a-2jJvsv-MY36xN3B7QXsVULbug86ibf-cjqRGTZ5EJszGmkeqCqDld4vq1ILY2x0ce_xMnh-OitZAF8IknOBjybTbqNCrvLvwX8qFHM/s640/02_Display+Estimated+Exectution+Plan.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="color: red;"&gt;03. 消失的 Execution Plan!&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
無可分析!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
因為要等到 執行階段，動態傳入資料表名稱 後，Query Optimizer 方能依據傳入的資料表資訊，分析 SQL 陳述式，判斷出取得所需資料的最有效方式。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;03_Display Estimated Execution Plan&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5xRuzx2JJusNhGTXKqfqwLwAukWk8ryxMZQ1GhaFOeVKzRmlKdbARkKY8K3raPwwFJL39vaYrdrPEnbWIXFXME5npPTpUIt0O9RW9tZ4uwp_qL2ThtG22S7N0mtCka6SSybAMc-Uq_WE/s1600/03_Display+Estimated+Exectution+Plan.png" imageanchor="1"&gt;&lt;img border="0" height="516" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5xRuzx2JJusNhGTXKqfqwLwAukWk8ryxMZQ1GhaFOeVKzRmlKdbARkKY8K3raPwwFJL39vaYrdrPEnbWIXFXME5npPTpUIt0O9RW9tZ4uwp_qL2ThtG22S7N0mtCka6SSybAMc-Uq_WE/s640/03_Display+Estimated+Exectution+Plan.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
04. 改用 &lt;span style="color: blue;"&gt;Include Actual Execution Plan。&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;點選 Include Actual Execution Plan，執行 2 段 SQL 陳述式。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;04_Exec_Proc_Include Actual Execution Plan&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZ8jlIzO6HPG5fAK-XHuBjK4A_gM320n422jycOBAdk65PwNeFrerw_zD9zUpFvV8QK-nbX2fXhW3s4QC2LknpenWHLjh416VvTvc92jAUzIkyQKIUP9BjxQiCUKSu2LSqjbyF1vkzr8k/s1600/04_Exec_Proc_Include+Actual+Exectution+Plan.png" imageanchor="1"&gt;&lt;img border="0" height="292" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZ8jlIzO6HPG5fAK-XHuBjK4A_gM320n422jycOBAdk65PwNeFrerw_zD9zUpFvV8QK-nbX2fXhW3s4QC2LknpenWHLjh416VvTvc92jAUzIkyQKIUP9BjxQiCUKSu2LSqjbyF1vkzr8k/s640/04_Exec_Proc_Include+Actual+Exectution+Plan.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
05. 檢視 Stored Procedure 執行結果。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
資料表變數:&amp;nbsp;TransactionHistory&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;回傳 0 筆資料列。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
資料表變數:&amp;nbsp;TransactionHistoryArchive&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;回傳 215 筆資料列。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;05_Exec_Proc_Include Actual Execution Plan&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLYZUIp_ANKdJGYcjMkW61cBthGZkVkAKegZ1HGAkYEVxPHnTqM8rBt5P5BZlinLkbd5KkmkbN2YZkFMfCcS8EASeJIVxQE-AIAZoC-SbzzSyyy72WMd0ZSqGw66fH4TlFL9yxUv-I9q8/s1600/05_Exec_Proc_Include+Actual+Exectution+Plan.png" imageanchor="1"&gt;&lt;img border="0" height="366" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLYZUIp_ANKdJGYcjMkW61cBthGZkVkAKegZ1HGAkYEVxPHnTqM8rBt5P5BZlinLkbd5KkmkbN2YZkFMfCcS8EASeJIVxQE-AIAZoC-SbzzSyyy72WMd0ZSqGw66fH4TlFL9yxUv-I9q8/s640/05_Exec_Proc_Include+Actual+Exectution+Plan.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
06. 檢視 Execution Plan。&lt;br /&gt;
&lt;br /&gt;
資料表變數:&amp;nbsp;TransactionHistory&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;回傳 0 筆資料列。&lt;/li&gt;
&lt;li&gt;Clustered Index Scan。&lt;/li&gt;
&lt;li&gt;有 Missing Index。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
資料表變數:&amp;nbsp;TransactionHistoryArchive&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;回傳 215 筆資料列。&lt;/li&gt;
&lt;li&gt;Clustered Index Scan。&lt;/li&gt;
&lt;li&gt;有 Missing Index。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;06_View_Actual_Execution_Plan&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixYTs-WxR-D02i7DREAcKPLSfZ9eesDGMCVaOL8cargBsOoTfqia7ksolFEx_txLOQIL7X1cgRLkK3qhvoOzMuGG8Ahal2GfyV7Xchi9ly7kQ4wtwB1zc4ulka6ryCtlT2BbgcLHNKKWk/s1600/06_View_Actual_Execution_Plan.png" imageanchor="1"&gt;&lt;img border="0" height="352" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixYTs-WxR-D02i7DREAcKPLSfZ9eesDGMCVaOL8cargBsOoTfqia7ksolFEx_txLOQIL7X1cgRLkK3qhvoOzMuGG8Ahal2GfyV7Xchi9ly7kQ4wtwB1zc4ulka6ryCtlT2BbgcLHNKKWk/s640/06_View_Actual_Execution_Plan.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
07. 檢視 Plan Cache&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1st: CREATE PROC pr_DynamicTable @tbname sysname, ...&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;LastElapsedTime,&amp;nbsp;last_logical_reads 等，都是 NULL。&lt;/li&gt;
&lt;li&gt;ExecutionCount 累積到 2。&lt;/li&gt;
&lt;li&gt;ObjType: Proc。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
2nd 與 3rd:&amp;nbsp;SET STATISTICS XML OFF 與 SET STATISTICS XML ON&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;這是因為啟用了 Include Actual Execution Plan 功能，SQL Server 使用&amp;nbsp;XML 文件格式來產生 SQL 陳述式執行狀況的詳細資料。&lt;/li&gt;
&lt;li&gt;LastElapsedTime,&amp;nbsp;last_logical_reads 等，都是 NULL。&lt;/li&gt;
&lt;li&gt;ObjType: Prepared。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
4th: (@TransactionDate datetime) SELECT [TransactionID],..&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;LastElapsedTime,&amp;nbsp;last_logical_reads 等，都有顯示出資料。&lt;/li&gt;
&lt;li&gt;這是 實際執行 SQL 陳述式後產生的 效能資料。&lt;/li&gt;
&lt;li&gt;點選 [QueryPlan]，可以看到 實際執行的 Execution Plan。&lt;/li&gt;
&lt;li&gt;ObjType: Prepared。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
5th: (@TransactionDate datetime) SELECT [TransactionID],..&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;LastElapsedTime,&amp;nbsp;last_logical_reads 等，都有顯示出資料。&lt;/li&gt;
&lt;li&gt;這是 實際執行 SQL 陳述式後產生的 效能資料。&lt;/li&gt;
&lt;li&gt;點選 [QueryPlan]，可以看到 實際執行的 Execution Plan。&lt;/li&gt;
&lt;li&gt;ObjType: Prepared。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;07_Plan_Cache&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLzTnvS7PvpmYx2_J2FrCZJSpxXsMY2B04KIe2tsgP59OqqfsuEK_l91IQgYhMbPBVPU8oHcgmqJOrIpjon5ZmVz65Pi4XFSZJ0BYIG079b7v6sfsPxcTEsaIE7XAy_UZltgCO2sWWFhg/s1600/07_Plan_Cache.png" imageanchor="1"&gt;&lt;img border="0" height="64" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLzTnvS7PvpmYx2_J2FrCZJSpxXsMY2B04KIe2tsgP59OqqfsuEK_l91IQgYhMbPBVPU8oHcgmqJOrIpjon5ZmVz65Pi4XFSZJ0BYIG079b7v6sfsPxcTEsaIE7XAy_UZltgCO2sWWFhg/s640/07_Plan_Cache.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
08. 可以看到 [ParameterList] 與 [QueryPlan] 都有實際資料。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;08_Plan_Cache&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLI7gmAZvgPbR5eSWTNmDgmqXjcKahzfpVs-7xfRJdPdRbGBTSLYjcDszdWu_f24qC4w5tGYjfg6RCz0qlOkPPrgibzdsJC3boN18YaWfuK3_jVvpdERH5WIyXsojoaZNw1XVAWpuxhE0/s1600/08_Plan_Cache.png" imageanchor="1"&gt;&lt;img border="0" height="72" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLI7gmAZvgPbR5eSWTNmDgmqXjcKahzfpVs-7xfRJdPdRbGBTSLYjcDszdWu_f24qC4w5tGYjfg6RCz0qlOkPPrgibzdsJC3boN18YaWfuK3_jVvpdERH5WIyXsojoaZNw1XVAWpuxhE0/s640/08_Plan_Cache.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: red; font-size: large;"&gt;消失的 Execution Plan&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;看不到 實際執行的 Execution Plan!&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;09_1 Missing Execution Plan&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRh5Ehi61pjnwFkhGWEk3KcwOKMJ_UNVEOlS2wRt3pG9ChOb8-tWofkFaOHOkqbPlnrcVgk8ZUDu5e_VIqL_D1sg-N6udKHYtXioNnBTwZfCKRUrmTfjYZo1NWTyfxAiwl145VzbdCphg/s1600/09_6.png" imageanchor="1"&gt;&lt;img border="0" height="264" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRh5Ehi61pjnwFkhGWEk3KcwOKMJ_UNVEOlS2wRt3pG9ChOb8-tWofkFaOHOkqbPlnrcVgk8ZUDu5e_VIqL_D1sg-N6udKHYtXioNnBTwZfCKRUrmTfjYZo1NWTyfxAiwl145VzbdCphg/s640/09_6.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;Execution Plan 藏在這裡 ...&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
-- figure 09_2&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTvNXbqVzKYgyRUnTYeU5GKleCKhTZN_fpQJfXdggrguVb3pyEAafEayRxwTxagYTWZEqRhSkvuo_7ubBdfFFYpwlE8_5L-qG55RPN7CtH61E8X2OFHjk9g9RTj3uIvbSc1PXGbwngewU/s1600/09_7.png" imageanchor="1"&gt;&lt;img border="0" height="264" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTvNXbqVzKYgyRUnTYeU5GKleCKhTZN_fpQJfXdggrguVb3pyEAafEayRxwTxagYTWZEqRhSkvuo_7ubBdfFFYpwlE8_5L-qG55RPN7CtH61E8X2OFHjk9g9RTj3uIvbSc1PXGbwngewU/s640/09_7.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
09. 重複 執行多次 Stored Procedure。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;資料表變數:&amp;nbsp;TransactionHistory，再執行 10 次。&lt;/li&gt;
&lt;li&gt;資料表變數:&amp;nbsp;TransactionHistoryArchive，再執行 20 次。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;11_Run many times&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvXQ1N_MyPb1950dSSC84Y7p8uwI9t07cAWQrAl43EUfM1Zdma0662HR18cgTJuCWPF1hG-wZ4MZ1gxcON6C51m6cDbA-wb1STNXH8XCxEi4A5G1L8ri5aIYvOxqjXGqdg5vTC44MbORc/s1600/11_Run+many+times.png" imageanchor="1"&gt;&lt;img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvXQ1N_MyPb1950dSSC84Y7p8uwI9t07cAWQrAl43EUfM1Zdma0662HR18cgTJuCWPF1hG-wZ4MZ1gxcON6C51m6cDbA-wb1STNXH8XCxEi4A5G1L8ri5aIYvOxqjXGqdg5vTC44MbORc/s640/11_Run+many+times.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
10. 觀察 Plan Cache。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;1st:&amp;nbsp;ExecutionCount 累積到 32。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;ObjType: Proc。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;2nd: 資料表變數:&amp;nbsp;TransactionHistoryArchive，ExecutionCount 累積到 21。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;ObjType: Prepared。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;3rd: 資料表變數:&amp;nbsp;TransactionHistory，ExecutionCount 累積到 11。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;ObjType: Prepared。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;12_Plan_Cache&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyHietvj4j7dFlnzIaTTCW8oot1R545Wja_n_0AnM3d7ddpQENiIC3pREKMdK8u-rWrCl-Vzx6TPlc3_BpFFXu0OHUuRFUezcTqWUfPhL9Xh9E3qMXbYx6PhSDU8Lw7lWYNVPBqnltJ4Y/s1600/12_Plan_Cache.png" imageanchor="1"&gt;&lt;img border="0" height="76" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyHietvj4j7dFlnzIaTTCW8oot1R545Wja_n_0AnM3d7ddpQENiIC3pREKMdK8u-rWrCl-Vzx6TPlc3_BpFFXu0OHUuRFUezcTqWUfPhL9Xh9E3qMXbYx6PhSDU8Lw7lWYNVPBqnltJ4Y/s640/12_Plan_Cache.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
11. 輸入更多不同的 Parameter value&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
資料表變數: TransactionHistory&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;但日期更換為:&amp;nbsp;2013-06-10,&amp;nbsp;2013-06-11,&amp;nbsp;2013-06-12&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
資料表變數: TransactionHistoryArchive&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;但日期更換為:&amp;nbsp;2013-06-10,&amp;nbsp;2013-06-11,&amp;nbsp;2013-06-12&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure 13_ Different parameter value with the same table&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqQKnxEZFTkb_Q7MUnXHaf9c9nSSRl7xyXM3JUoB66i1NXQkMIAaHtsqmIN-e6WabRdw_9P_6sX5_0AELZdzg1q8vnv0ZbzveokD7eoncgjQ2DXcJ_iuan2l4yb-_kaGqPYrf6LuTAMbI/s1600/13_Differnet+parameter+value+with+the+same+table.png" imageanchor="1"&gt;&lt;img border="0" height="218" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqQKnxEZFTkb_Q7MUnXHaf9c9nSSRl7xyXM3JUoB66i1NXQkMIAaHtsqmIN-e6WabRdw_9P_6sX5_0AELZdzg1q8vnv0ZbzveokD7eoncgjQ2DXcJ_iuan2l4yb-_kaGqPYrf6LuTAMbI/s640/13_Differnet+parameter+value+with+the+same+table.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
12. 觀察 Plan Cache。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;1st:&amp;nbsp;ExecutionCount 累積到 38。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;ObjType: Proc。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;2nd: 資料表變數:&amp;nbsp;TransactionHistoryArchive，ExecutionCount 累積到 24。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;使用相同資料表，雖然 Parameter value不同，但可以 Reuse Execution Plan。&lt;/li&gt;
&lt;li&gt;ObjType: Prepared。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;3rd: 資料表變數:&amp;nbsp;TransactionHistory，ExecutionCount 累積到 14。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;使用相同資料表，雖然 Parameter value不同，但可以 Reuse Execution Plan。&lt;/li&gt;
&lt;li&gt;ObjType: Prepared。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;Dynamic SQL: sp_executesql&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;ObjType: Prepared&lt;/li&gt;
&lt;li&gt;使用 Parameter Sniffing 機制來 Re-Use Execution Plan。&lt;/li&gt;
&lt;li&gt;必須面對 Parameter Sniffing 所帶來的 Side Effects。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure 14_Plan Cache&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5jpQFaNpxLfcPEznQNxBfqCodkspNh4KdDWFXn6ULpSv4wcHNGM9krZbHB_fzL-rx6f8R0qYL9hyphenhyphen9MA7jNzgold4zeDbDvwGK9V49KeGFRLCXgx-Er36ohrTg6R7BS8xCnFW8sOwUYuo/s1600/14_Plan+Cache.png" imageanchor="1"&gt;&lt;img border="0" height="66" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5jpQFaNpxLfcPEznQNxBfqCodkspNh4KdDWFXn6ULpSv4wcHNGM9krZbHB_fzL-rx6f8R0qYL9hyphenhyphen9MA7jNzgold4zeDbDvwGK9V49KeGFRLCXgx-Er36ohrTg6R7BS8xCnFW8sOwUYuo/s640/14_Plan+Cache.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Dynamic SQL: &lt;/span&gt;&lt;span style="color: purple; font-size: x-large;"&gt;EXEC&lt;/span&gt;&lt;span style="color: blue; font-size: x-large;"&gt;,&amp;nbsp; Pass dynamic TABLE name variable&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;動態傳遞 資料表名稱 變數&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
改用 EXEC。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
01.&amp;nbsp;建立使用 Dynamic SQL: EXEC&amp;nbsp;動態傳遞 資料表變數 的 Stored Procedure。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;@tsql: 需要執行的 SQL 陳述式或批次。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;71_Proc_Pass dynamic TABLE name to EXEC&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi08UfmQ0fKJC0IkQVspEthzyMLN5h7Xha3edNajJUp-8p5LlWnxXTQtOM4xHI5jODTYGkUvWIr-qMSwZz_pFA3b7fTsy3bzZ9QrPS5UYJzvz3aIaaT30ePnmpoLmnn5TUEZbUjxeSkCYs/s1600/71_Proc_Pass+dynamic+TABLE+name+to+EXEC.png" imageanchor="1"&gt;&lt;img border="0" height="232" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi08UfmQ0fKJC0IkQVspEthzyMLN5h7Xha3edNajJUp-8p5LlWnxXTQtOM4xHI5jODTYGkUvWIr-qMSwZz_pFA3b7fTsy3bzZ9QrPS5UYJzvz3aIaaT30ePnmpoLmnn5TUEZbUjxeSkCYs/s640/71_Proc_Pass+dynamic+TABLE+name+to+EXEC.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 點選 Display Estimated Execution Plan，消失的 Execution Plan，無可分析!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;因為要等到 執行階段，動態傳入資料表名稱 後，Query Optimizer 方能依據傳入的資料表資訊，分析 SQL 陳述式，判斷出取得所需資料的最有效方式。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
03. 改用 Include Actual Execution Plan。&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
點選 Include Actual Execution Plan，執行以下多段 SQL 陳述式。&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
-- figure&amp;nbsp;72_Exec_Proc_pr_DynamicTable_EXEC&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEga9g38xF7z1SYMF5Cxcssa2-uIJx5avhyLqERIVBGCR70FTBGECa2f6V6-QysG7Cy3vxUpH80qrYG702pnlRpKNl4BP_o6lftLUaQNfvPHQ7dKiIYifcFLFuAiBc55xMpD3F1JrOS2AOE/s1600/72_Exec_Proc_pr_DynamicTable_EXEC.png" imageanchor="1"&gt;&lt;img border="0" height="630" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEga9g38xF7z1SYMF5Cxcssa2-uIJx5avhyLqERIVBGCR70FTBGECa2f6V6-QysG7Cy3vxUpH80qrYG702pnlRpKNl4BP_o6lftLUaQNfvPHQ7dKiIYifcFLFuAiBc55xMpD3F1JrOS2AOE/s640/72_Exec_Proc_pr_DynamicTable_EXEC.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
04. 觀察 Execution Plan。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1st: CREATE PROC pr_DynamicTable @tbname sysname, ...&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;LastElapsedTime,&amp;nbsp;last_logical_reads 等，都是 NULL。&lt;/li&gt;
&lt;li&gt;ExecutionCount 累積到 2。&lt;/li&gt;
&lt;li&gt;ObjType: Proc。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
2nd: 是重複執行 'TransactionHistoryArchive', '2013-07-30';&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;ExecutionCount 累積到 21。&lt;/li&gt;
&lt;li&gt;ObjType: Adhoc。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
3rd: 是重複執行 'TransactionHistory', '2013-07-30';&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;ExecutionCount 累積到 11。&lt;/li&gt;
&lt;li&gt;ObjType: Adhoc。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
4th~9th: 資料表變數: TransactionHistory 或是 TransactionHistoryArchive&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;但日期更換為:&amp;nbsp;2013-06-10,&amp;nbsp;2013-06-11,&amp;nbsp;2013-06-12&lt;/li&gt;
&lt;li&gt;ExecutionCount 都是 1&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;相同資料表，但 Parameter value不同，產生的 hash value 也不相同。&lt;/li&gt;
&lt;li&gt;導致無法 Reuse Execution Plan。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;ObjType: Adhoc。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;73_Plan_Cache&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0YY4Bv_Qt-4F3VnU-364rtKjNXqGfsvQl6M4xmeXig4TmUti4FICXYD5hZk0wYOf0W4OhwBytCp_jLQj9DujfcGIqq0-2fctUpo5OhQiLNZ0APygbwK-C9gwMe1OZkjpI7MYulNI9uYU/s1600/73_Plan_Cache.png" imageanchor="1"&gt;&lt;img border="0" height="116" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0YY4Bv_Qt-4F3VnU-364rtKjNXqGfsvQl6M4xmeXig4TmUti4FICXYD5hZk0wYOf0W4OhwBytCp_jLQj9DujfcGIqq0-2fctUpo5OhQiLNZ0APygbwK-C9gwMe1OZkjpI7MYulNI9uYU/s640/73_Plan_Cache.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
05. 觀察 Execution Plan，檢視 SQL statement 的 Parameter value。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Parameter value不同，產生的 hash value 也不相同，導致無法 Reuse Execution Plan。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;Dynamic SQL: EXEC&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
採取比對 hash 值&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;相同，就能重複使用 Execution Plan。&lt;/li&gt;
&lt;li&gt;不同，產生新的 Execution Plan。&lt;/li&gt;
&lt;li&gt;ObjType: Adhoc。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;74_Plan_Cache&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQKKbIEbXWadcc8jF35ZoVlrOIcwJYbeP_W6Dq0pyR4AvR28lBXOOKJitfn7JqTvr0D85sz4XBPhvwlpImsAWqfJ-3FyXCkoSJC9fubCPAIjpWueLdT91a0wTiNoI8RFN7Wsn8JHfd_c8/s1600/74_Plan_Cache.png" imageanchor="1"&gt;&lt;img border="0" height="112" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQKKbIEbXWadcc8jF35ZoVlrOIcwJYbeP_W6Dq0pyR4AvR28lBXOOKJitfn7JqTvr0D85sz4XBPhvwlpImsAWqfJ-3FyXCkoSJC9fubCPAIjpWueLdT91a0wTiNoI8RFN7Wsn8JHfd_c8/s640/74_Plan_Cache.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;QUOTENAME()&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
功能：傳回 Unicode 字串，且附加了分隔符號，以便使輸入字串成為有效的 [SQL Server] 分隔識別碼。&lt;br /&gt;
限制為 &lt;b&gt;&lt;span style="color: blue;"&gt;128 &lt;/span&gt;&lt;/b&gt;個字元。 大於 128 個字元的輸入會傳回 NULL。&lt;br /&gt;
&lt;br /&gt;
語法&lt;br /&gt;
QUOTENAME ( 'character_string' [ , 'quote_character' ] )&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
'quote_character'&lt;br /&gt;
這是用來當做分隔符號的單字元字串。&lt;br /&gt;
它可以是單引號 ( ' )、左或右方括弧 ( [] )、雙引號 ( " )、左或右括弧 ( () )、&lt;br /&gt;
大於或小於符號 ( &amp;gt;&amp;lt; )、左或右大括弧 ( {} ) 或反勾號 ( ` )。&lt;br /&gt;
&lt;br /&gt;
如果提供了無法接受的字元，則會傳回 NULL。&lt;br /&gt;
如果未指定 quote_character，就會使用方括號。&lt;br /&gt;
&lt;br /&gt;
用於面對 SQL Injection(資料隱碼)，建議搭配 QUOTENAME() 或 REPLACE()， 來 驗證 Dynamic SQL 使用的所有變數都已正確處理。&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Sample Code&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
20180917_Dynamic SQL Pass dynamic TABLE name variable&lt;br /&gt;
&lt;a href="https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing"&gt;https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
Reference&lt;br /&gt;
&lt;br /&gt;
[Case Study] Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (1)&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or.html"&gt;http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Parameter Sniffing: Dynamic SQL, sp_executesql and EXEC (Parameter Sniffing 與 動態 SQL)&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/parameter-sniffing-dynamic-sql.html"&gt;http://sharedderrick.blogspot.com/2018/08/parameter-sniffing-dynamic-sql.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
QUOTENAME (Transact-SQL)&lt;br /&gt;
&lt;a href="https://docs.microsoft.com/zh-tw/sql/t-sql/functions/quotename-transact-sql?view=sql-server-2017"&gt;https://docs.microsoft.com/zh-tw/sql/t-sql/functions/quotename-transact-sql?view=sql-server-2017&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
SQL 資料隱碼&lt;br /&gt;
&lt;a href="https://docs.microsoft.com/zh-tw/sql/relational-databases/security/sql-injection?view=sql-server-2017"&gt;https://docs.microsoft.com/zh-tw/sql/relational-databases/security/sql-injection?view=sql-server-2017&lt;/a&gt;</description><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTd4-1NUb4IM1fF1Xjrz3QcCR0945EU8biNLGeBa6P_ZhYLHXn_8JSowp2X0F4_FbIo4g6kNWluVySxMtmd34NMv4weJPxVKiPMJ0uAFN2idfkDRSo4pV0B-KhUoIfaN2l262tGMmLBJg/s72-c/03_Display+Estimated+Exectution+Plan.png" width="72"/><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><title>[Case Study] Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (5)</title><link>http://sharedderrick.blogspot.com/2018/09/case-study-parameter-sniffing-with-or.html</link><category>Performance Tuning</category><category>SQL Server</category><author>noreply@blogger.com (DerrickLaLa)</author><pubDate>Fri, 7 Sep 2018 07:16:00 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1420955872914622499.post-317798402712048603</guid><description>&lt;br /&gt;
延續前一篇文章：&lt;a href="http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or_31.html"&gt;[Case Study] Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (4)&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
一談起 Dynamic SQL，許多人以為要使用 sp_executesql 才是 對的、效能好的，但其實這是囫圇吞棗後的謬誤。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;sp_executesql，仍使用 Parameter Sniffing 機制來 Reuse Execution Plan&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;有機會發生重複使用了效能 不佳 Execution Plan，陷入效能更糟的窘境。&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;Dynamic SQL: EXEC，採取 Ad hoc Query 機制&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;採取比對 hash 值來 重複使用 Execution Plan，為各個輸入 parameter 值，建立 效能佳 的 Execution Plan。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;span style="color: blue; font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="color: blue; font-size: large;"&gt;方法總比困難多&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
在本案例中：&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;與 Dev Team 攜手合作，理解 Business 商務面的需求，改寫為 兩隻符合各自需求的 Stored Procedure，會是 執行效能最佳的解決方案!&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7C1PEDXML0-OWg53o3d7q9omd6XPcX-1GmzAN3wOPvQOUc5NStcdrTSRWpSvOJL3UGOxN_Fvj03CdKyUXwZcevwKZekl2Zjd7bCkfkLX_pFihxC5fN2FmH4hmtQ1suu0Ul5vRl9FRX7M/s1600/88_Plan_Explorer.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="629" data-original-width="1219" height="330" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7C1PEDXML0-OWg53o3d7q9omd6XPcX-1GmzAN3wOPvQOUc5NStcdrTSRWpSvOJL3UGOxN_Fvj03CdKyUXwZcevwKZekl2Zjd7bCkfkLX_pFihxC5fN2FmH4hmtQ1suu0Ul5vRl9FRX7M/s640/88_Plan_Explorer.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
繼續討論 Parameter Sniffing 的 因應之道：&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;使用 EXEC ... WITH RECOMPILE&lt;/li&gt;
&lt;li&gt;使用 sp_recompile&lt;/li&gt;
&lt;li&gt;修改 Stored Procedure，使用 Local Variables&lt;/li&gt;
&lt;li&gt;修改 Stored Procedure，使用 WITH RECOMPILE&lt;/li&gt;
&lt;li&gt;修改 Stored Procedure，使用 OPTION RECOMPILE&lt;/li&gt;
&lt;li&gt;改寫 Stored Procedure，使用 UNION ALL&lt;/li&gt;
&lt;li&gt;改寫&amp;nbsp;Stored Procedure，使用 IF ELSE&lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;改寫&amp;nbsp;Stored Procedure，使用 Dynamic SQL: EXEC&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;改寫&amp;nbsp;Stored Procedure，使用 Dynamic SQL: sp_executesql&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;因應需求，分別建立 Stored Procedure&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Parameter Sniffing with OR Operator issue,&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;當 Parameter Sniffing 遇上 OR 運算子(5)&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="color: blue; font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="color: blue; font-size: large;"&gt;&lt;/span&gt;&lt;br /&gt;
使用 UNION ALL 或 IF ELSE 改寫 Stored Procedure，確實可以讓 Query Optimizer 優化使用到更佳的索引。&lt;br /&gt;
&lt;br /&gt;
但改寫、分解 條件式邏輯，這是項大工程，需要與 SQL Developer 進一步討論、驗證與測試。&lt;br /&gt;
&lt;br /&gt;
其實還有其他解決方案，試試&amp;nbsp;Dynamic SQL: EXEC。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;8. 改寫 Stored Procedure，使用 Dynamic SQL: EXEC&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
說明：&lt;br /&gt;
&lt;br /&gt;
Dynamic SQL: EXEC&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;採取 Ad hoc Query 機制來 重複使用 Execution Plan&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;採取比對 hash 值&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;相同，就能重複使用 Execution Plan。&lt;/li&gt;
&lt;li&gt;不同，產生新的 Execution Plan。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;為各個輸入 parameter 值，建立 效能佳 的 Execution Plan。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;但若每次輸入 parameter 值完全不會重複，則每次執行都會編譯，耗用系統資源。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;減少因 Parameter Sniffing 機制，重複使用了效能 不佳 Execution Plan，導致效能更糟的問題。&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
注意事項：&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;修改 Stored Procedure 程式碼，牽扯版本問題。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;需要與 SQL Developer 人員溝通討論。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
01.&amp;nbsp;建立使用 Dynamic SQL: EXEC 的 Stored Procedure。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;必須修改原來的程式碼。&lt;/li&gt;
&lt;li&gt;宣告 字串變數 @sql 存放 SQL statement。&lt;/li&gt;
&lt;li&gt;傳入 parameter&amp;nbsp;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;可能需要轉型為 Character strings 類型。&lt;/li&gt;
&lt;li&gt;以及對 NULL 值的處理。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;基本上&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;採用組合 SQL statement 方式。這是與原始程式雷同。&lt;/li&gt;
&lt;li&gt;沒有像 UNION ALL 或 IF ELSE 般分拆改寫。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;由於採取組 SQL statement 方式，程式碼可讀性略差，是會增加維護成本。&lt;/li&gt;
&lt;/ul&gt;
-- figure&amp;nbsp;91_ALTER Proc Dynamic SQL EXEC&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglcqQazxd-xjnJWHoMIUksnX4_Cwn3J76hDPAX39PPP8_qdZasyKxxIV7udKZxwcv-G8e_lX9i1YRhj_nqD4SFzP3oOTMdYYiTDulE4G2ftkxOY5sK44LFxWCNcG8D4Q53tUm6Y4LoqDM/s1600/91_ALTER+Proc+Dynamic+SQL+EXEC.png" imageanchor="1"&gt;&lt;img border="0" height="342" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglcqQazxd-xjnJWHoMIUksnX4_Cwn3J76hDPAX39PPP8_qdZasyKxxIV7udKZxwcv-G8e_lX9i1YRhj_nqD4SFzP3oOTMdYYiTDulE4G2ftkxOY5sK44LFxWCNcG8D4Q53tUm6Y4LoqDM/s640/91_ALTER+Proc+Dynamic+SQL+EXEC.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 執行 使用 Dynamic SQL: EXEC 的 Stored Procedure。&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
分別輸入 NULL 與 43659。&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;當輸入 NULL:&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;取回全部資料，回傳 118,744 rows，使用 Clustered Index Scan。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;當輸入 43659:&amp;nbsp;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;取回指定 SalesOrderID 的資料，回傳 12 rows。&lt;/li&gt;
&lt;li&gt;經 Query Optimizer 執行優化後，使用 Clustered Index &lt;span style="color: blue;"&gt;Seek&lt;/span&gt;。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;沒有使用到效率差的 Clustered Index Scan。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;這是有提升執行效能的 Execution Plan。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
進一步來檢視 Execution Plan。&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
-- figure&amp;nbsp;92_EXEC Proc Dynamic SQL EXEC&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0A6s_8IvV5c8F_KYCsktHsNUaAAf5-bhjCeoNsnwhkbzHyOCVEsdFtEjbnkEiZ9AAsRFsVtVOM9LDEX-EbxeFcHFH3VXz7wn1Gd0KGjf0MgROkP6uo7wZmNTn-AiNC_xmCtGted9ByrM/s1600/92_EXEC+Proc+Dynamic+SQL+EXEC.png" imageanchor="1"&gt;&lt;img border="0" height="186" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0A6s_8IvV5c8F_KYCsktHsNUaAAf5-bhjCeoNsnwhkbzHyOCVEsdFtEjbnkEiZ9AAsRFsVtVOM9LDEX-EbxeFcHFH3VXz7wn1Gd0KGjf0MgROkP6uo7wZmNTn-AiNC_xmCtGted9ByrM/s640/92_EXEC+Proc+Dynamic+SQL+EXEC.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03.&amp;nbsp;觀察 Execution Plan:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
當輸入參數是 NULL&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;使用 Clustered Index Scan。&lt;/li&gt;
&lt;li&gt;Actual Rows: 118,744。&lt;/li&gt;
&lt;li&gt;Est Rows: 116,323，這是 Estimated Number of Rows。&lt;/li&gt;
&lt;li&gt;Reads: 2,249，這是 Logical Reads。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;93_Plan_Explorer&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbXjg8WpFXpldBqkq21LOwX9t09k5WNcEfiLZWzwuo3ECK9tdGH7autwrL0vDzivalavYQkXfN4qcRKPg32AL57RQ0RTQdYJJr-Lym96i4JujAvSEu7Z4FFJXARTsb0huKVqXhD7l4Uh0/s1600/93_Plan_Explorer.png" imageanchor="1"&gt;&lt;img border="0" height="330" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbXjg8WpFXpldBqkq21LOwX9t09k5WNcEfiLZWzwuo3ECK9tdGH7autwrL0vDzivalavYQkXfN4qcRKPg32AL57RQ0RTQdYJJr-Lym96i4JujAvSEu7Z4FFJXARTsb0huKVqXhD7l4Uh0/s640/93_Plan_Explorer.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
04.&amp;nbsp;觀察 Execution Plan:&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
當輸入參數是 43659&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;使用 Clustered Index Seek。&lt;/li&gt;
&lt;li&gt;Actual Rows: 12。&lt;/li&gt;
&lt;li&gt;Est Rows: 12，這是 Estimated Number of Rows。&lt;/li&gt;
&lt;li&gt;Reads: 12，這是 Logical Reads。&lt;/li&gt;
&lt;li&gt;對比使用 UNION ALL，Reads 是 372，UNION ALL 使用更多的 Logical Reads。&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
-- figure 114_GetSalesList_DynamicSQL_EXEC 43659&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_Y3sCiS2JMWexeBquBFnV8wZVNmdKxC6W-BxfVJqt_jFFSY_chiXoefcwUM23jeaX4AqY_hIH_aEndXIbb1lRY_okrDj1KrEM-aqTkhzz7rwWra6WqWMteT1Qn_UjWEbKwr9Zly-y4SA/s1600/114_EXEC.png" imageanchor="1"&gt;&lt;img border="0" height="264" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_Y3sCiS2JMWexeBquBFnV8wZVNmdKxC6W-BxfVJqt_jFFSY_chiXoefcwUM23jeaX4AqY_hIH_aEndXIbb1lRY_okrDj1KrEM-aqTkhzz7rwWra6WqWMteT1Qn_UjWEbKwr9Zly-y4SA/s640/114_EXEC.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;94_Plan_Explorer&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSdPrqLPTCmEumSzYcxtqK1no2V_W3QTOJHGaqL0B4n8xJLf1wL467tINZoc7WAlDurYICpJT_-TKZK5L2jHC51yUhDuKWUu1MFjAMPMkn8s97aJludM3p9wBlnWoyxKcRqAMC3G_-M_w/s1600/94_Plan_Explorer.png" imageanchor="1"&gt;&lt;img border="0" height="280" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSdPrqLPTCmEumSzYcxtqK1no2V_W3QTOJHGaqL0B4n8xJLf1wL467tINZoc7WAlDurYICpJT_-TKZK5L2jHC51yUhDuKWUu1MFjAMPMkn8s97aJludM3p9wBlnWoyxKcRqAMC3G_-M_w/s640/94_Plan_Explorer.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
05. 使用不同的輸入 parameter，分別執行。&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;刻意設計，有 2 次使用相同的輸入 parameter。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;95_Execute many time with different parameter&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKUYpVs6u4kAw_XMvuLOSdMxByGKlUAbjH7g3WpK3uNW8In3ypVRligsC5Y63qwoBpPoaXhifSciaJtXvzVY7F2nat8SKpJwYlnzTUNU9-H8RrbkOYx1goCGNy4JewfHV15NHnP_B4hd0/s1600/95_Execute+many+time+with+different+parameter.png" imageanchor="1"&gt;&lt;img border="0" height="184" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKUYpVs6u4kAw_XMvuLOSdMxByGKlUAbjH7g3WpK3uNW8In3ypVRligsC5Y63qwoBpPoaXhifSciaJtXvzVY7F2nat8SKpJwYlnzTUNU9-H8RrbkOYx1goCGNy4JewfHV15NHnP_B4hd0/s640/95_Execute+many+time+with+different+parameter.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
06. 由 Cache ，觀察 Performance data&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;確認 Reuse Execution Plan。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;ExecutionCount: 2，就是先前刻意設計有 2 次使用相同的輸入 parameter。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;ObjType: Adhoc&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
Dynamic SQL: EXEC&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;採取比對 hash 值&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;相同，重複使用 Execution Plan。&lt;/li&gt;
&lt;li&gt;不同，產生新的 Execution Plan。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure 96_Adhoc_Execution_Plan&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLc8gGvfmVDebJpn8WENwDD2Nb2Sl-3DMi6kHrcRuWqU9J1M73b0xCz61HFTMPkBybjYlA7wuWz4-hXc96P2I8PsTedBZlo4bcD3tnH4B_NGy_-FtDENXlK3yabLbzeVgMM5OS1riSFkE/s1600/96_Adhoc_Execution_Plan.png" imageanchor="1"&gt;&lt;img border="0" height="62" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLc8gGvfmVDebJpn8WENwDD2Nb2Sl-3DMi6kHrcRuWqU9J1M73b0xCz61HFTMPkBybjYlA7wuWz4-hXc96P2I8PsTedBZlo4bcD3tnH4B_NGy_-FtDENXlK3yabLbzeVgMM5OS1riSFkE/s640/96_Adhoc_Execution_Plan.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dynamic SQL: EXEC 的 特色：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;為各個輸入 parameter 值，建立合適的 Execution Plan。&lt;/li&gt;
&lt;li&gt;採取 Ad hoc Query 機制來 重複使用 Execution Plan&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;比對 hash 值，若不同時，就產生新的 Execution Plan。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;若每次輸入 parameter 值完全不會重複，則每次執行都會編譯，耗用系統資源。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;li&gt;減少因 Parameter Sniffing 機制，重複使用效能不佳 Execution Plan，導致效能更糟的問題。&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;9. 改寫 Stored Procedure，使用 Dynamic SQL: sp_executesql&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
一談起 Dynamic SQL，許多人都以為要使用 sp_executesql 才是 對的、效能好的，但其實這是囫圇吞棗後的謬誤。&lt;br /&gt;
&lt;br /&gt;
若能正確理解 sp_executesql，方能避免因故重複使用效率差的 Execution Plan，導致 執行效能更糟的窘境。&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
說明&lt;br /&gt;
&lt;br /&gt;
Dynamic SQL: sp_executesql&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;使用 Parameter Sniffing 機制來 Reuse Execution Plan。&lt;/li&gt;
&lt;li&gt;必須面對 Parameter Sniffing 所帶來的 Side Effects。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
注意事項&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;修改 Stored Procedure 程式碼，牽扯版本問題。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;需要與 SQL Developer 人員溝通討論。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
01.&amp;nbsp;建立使用 Dynamic SQL: sp_executesql&amp;nbsp;的 Stored Procedure。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;必須修改原來的程式碼。&lt;/li&gt;
&lt;li&gt;宣告 字串變數 @sql 存放 SQL statement，資料類型需要是 Unicode。&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;li&gt;傳入 parameter&amp;nbsp;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;可能需要轉型為 Character strings 類型。&lt;/li&gt;
&lt;li&gt;以及對 NULL 值的處理。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;基本上&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;採用組合 SQL statement 方式。這是與原始程式雷同。&lt;/li&gt;
&lt;li&gt;沒有像 UNION ALL 或 IF ELSE 般分拆改寫。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;由於採取組 SQL statement 方式，程式碼可讀性略差，是會增加維護成本。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;101_ALTER Proc Dynamic SQL sp_executesql&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLbwlNUkrtUxR_gbbSTsp6T9a7Li_pJQgkrkuaSgbhLp6M557hvwJa3oD928hn6vQg9WnP4a_ESWJt47Sbp13lTxhk6CsU2D0FVDqpFZhiPEGwLVbUpV0oDnQvC2SeTj3AvX2wa_bPU0s/s1600/101_ALTER+Proc+Dynamic+SQL+sp_executesql.png" imageanchor="1"&gt;&lt;img border="0" height="336" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLbwlNUkrtUxR_gbbSTsp6T9a7Li_pJQgkrkuaSgbhLp6M557hvwJa3oD928hn6vQg9WnP4a_ESWJt47Sbp13lTxhk6CsU2D0FVDqpFZhiPEGwLVbUpV0oDnQvC2SeTj3AvX2wa_bPU0s/s640/101_ALTER+Proc+Dynamic+SQL+sp_executesql.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 執行 使用 Dynamic SQL: sp_executesql 的 Stored Procedure。&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
分別輸入 NULL 與 43659。&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;當輸入 NULL:&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;取回全部資料，回傳 118,744 rows，使用 Clustered Index &lt;span style="color: red;"&gt;Scan&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;當輸入 43659:&amp;nbsp;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;取回指定 SalesOrderID 的資料，回傳 12 rows，但卻仍是使用 Clustered Index &lt;span style="color: red;"&gt;Scan&lt;/span&gt;。&lt;/li&gt;
&lt;li&gt;Dynamic SQL: sp_executesql 使用 Parameter Sniffing 機制來 Re-Use Execution Plan。&lt;/li&gt;
&lt;li&gt;雖然節省了編譯 Execution Plan 的 CPU 資源，但卻因故誤用效能不佳的 Bad Execution Plan，導致耗用更多的系統資源！&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Dynamic SQL: sp_executesql&lt;br /&gt;
必須面對 誤用效能不佳的 Bad Execution Plan，所帶來的 Side Effects。&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
-- figure&amp;nbsp;102_EXEC Proc Dynamic SQL sp_executesql&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0wnJ4FUdLtlLgClhn7l1smBin3FCmxOMgf81vU1e8B-Ypxmc8j8GITwc908-7zn5Hy9yAEGp-S72V4ux0KDwqmWI2LeAxbXsC4DteH5aInjrb8DxPb3FiBOxceHDM0YcoOY6PCd4TptM/s1600/102_EXEC+Proc+Dynamic+SQL+sp_executesql.png" imageanchor="1"&gt;&lt;img border="0" height="224" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0wnJ4FUdLtlLgClhn7l1smBin3FCmxOMgf81vU1e8B-Ypxmc8j8GITwc908-7zn5Hy9yAEGp-S72V4ux0KDwqmWI2LeAxbXsC4DteH5aInjrb8DxPb3FiBOxceHDM0YcoOY6PCd4TptM/s640/102_EXEC+Proc+Dynamic+SQL+sp_executesql.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 觀察 Execution Plan&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;輸入 NULL&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
在 Proc 內使用 Dynamic SQL: sp_executesql&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Parameter Sniffing: Reuse Execution Plan&lt;/li&gt;
&lt;li&gt;僅第 1 次 有編譯產生 Execution Plan，之後都是共用同一份 Execution Plan。&lt;/li&gt;
&lt;li&gt;執行 10 次，即便是輸入不同的參數值，都是共用同一份 Execution Plan。&lt;/li&gt;
&lt;li&gt;節省 編譯 Execution Plan 的資源。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;ul style="background-color: white; color: #222222; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13.2px; line-height: 1.4; margin: 0.5em 0px; padding: 0px 2.5em;"&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;103_Plan_Explorer&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7gx7VJSZDCGnivXjU6MgO5-vuB-kEgWM_oWFDDAk-izH9oRGOKz8pkwyYJNbvLI-0uwo0RmcSiB3B8kmWkuk_aOg_CjIbh_BBt124YUPJQsCVW1UT9Kud2wzocZMqCEj6UZj4FnVdc-c/s1600/103_Plan_Explorer.png" imageanchor="1"&gt;&lt;img border="0" height="346" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7gx7VJSZDCGnivXjU6MgO5-vuB-kEgWM_oWFDDAk-izH9oRGOKz8pkwyYJNbvLI-0uwo0RmcSiB3B8kmWkuk_aOg_CjIbh_BBt124YUPJQsCVW1UT9Kud2wzocZMqCEj6UZj4FnVdc-c/s640/103_Plan_Explorer.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
04. 觀察 Execution Plan&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;輸入 43659&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;104_Plan_Explorer&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQ3bvuiCl2UJuMsFqsCcXQ2xDeP5YkgXYgYkO1HFMhZEYPCxpGlZ2w8foTZwqDwr9YcOGnRK9Rnc867Tz_zX4q_80yYGG05W-Mp4u1NxBqQbYNloy8rUK_szC_9gjNvw8Kxqpsi9ob3WQ/s1600/104_Plan_Explorer.png" imageanchor="1"&gt;&lt;img border="0" height="346" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQ3bvuiCl2UJuMsFqsCcXQ2xDeP5YkgXYgYkO1HFMhZEYPCxpGlZ2w8foTZwqDwr9YcOGnRK9Rnc867Tz_zX4q_80yYGG05W-Mp4u1NxBqQbYNloy8rUK_szC_9gjNvw8Kxqpsi9ob3WQ/s640/104_Plan_Explorer.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
05.&amp;nbsp;執行 GetSalesList_DynamicSQL_sp_executesql&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;執行 6 次。&lt;/li&gt;
&lt;li&gt;但第 2 與 3 次的輸入 parameter 都是相同。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;105_Parameter Sniffing reuse execution plan&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRRv9RzI0512Q8zzmtq2WAjWCi7smVKHqri26EucPGymleEnvIRvo55Pi3sMUZJ8YiD2343ttN-RjF1AeZtXvmc-m0_N7AZHkgNpAS3W9ECED-CZLsWjoNdaFlY4bDF3Ui55vP4aE3iIo/s1600/105_Parameter+Sniffing+reuse+execution+plan.png" imageanchor="1"&gt;&lt;img border="0" height="224" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRRv9RzI0512Q8zzmtq2WAjWCi7smVKHqri26EucPGymleEnvIRvo55Pi3sMUZJ8YiD2343ttN-RjF1AeZtXvmc-m0_N7AZHkgNpAS3W9ECED-CZLsWjoNdaFlY4bDF3Ui55vP4aE3iIo/s640/105_Parameter+Sniffing+reuse+execution+plan.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
06. 由 Cache，觀察 Performance Data&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;ExecutionCount: 6。&lt;/li&gt;
&lt;li&gt;ObjType: Prepared。&lt;/li&gt;
&lt;li&gt;重複使用同一份 Execution Plan。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
Dynamic SQL: sp_executesql&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;採取 Parameter Sniffing 機制來 Reuse Execution Plan。&lt;/li&gt;
&lt;li&gt;必須面對 因故重複使用效率差的 Execution Plan，所帶來的 Side Effects。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;106_Prepared_Execution_Plan&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijYY4r8RsrvM-XNQ9Xu1FAsKWGaBc91OPvhyphenhyphentgoEZvn-6P7QgsAWEG-WXxXVtJVYl6HlL6mgXNsnTV80tAJIuDTEi9816t7-r6FodqquvMs0GSVPyhlUIl2HeL_eUbDhCcAODpshRVtjc/s1600/105_Prepared_Execution_Plan.png" imageanchor="1"&gt;&lt;img border="0" height="38" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijYY4r8RsrvM-XNQ9Xu1FAsKWGaBc91OPvhyphenhyphentgoEZvn-6P7QgsAWEG-WXxXVtJVYl6HlL6mgXNsnTV80tAJIuDTEi9816t7-r6FodqquvMs0GSVPyhlUIl2HeL_eUbDhCcAODpshRVtjc/s640/105_Prepared_Execution_Plan.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;10. 因應需求，分別建立 Stored Procedure&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Use that big brain of yours to think your way out! Look for a new angle.&lt;br /&gt;
&lt;br /&gt;
還有什麼方法，可以有效解決 因故重複使用效率差的 Execution Plan 呢？&lt;br /&gt;
記得這句話：方法總比困難多。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
回顧一下&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
條件式:&amp;nbsp; WHERE (@SalesOrderID IS NULL OR sd.SalesOrderID = @SalesOrderID)&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;@SalesOrderID IS NULL:&amp;nbsp;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;當 @SalesOrderID 是 NULL 時，取回&lt;span style="color: red;"&gt;全部的資料，回傳 118,744 rows&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;sd.SalesOrderID = @SalesOrderID:&amp;nbsp;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;取回 指定的 SalesOrderID 的 資料，&lt;span style="color: blue;"&gt;回傳 12 rows&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
以 Index 使用策略來看：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;這兩個條件式，以執行效能角度來看，應該是使用不同的 Index 存取方式，例如：Index Scan、Index Seek 等。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbDetVS2k71BK22CksHYFb1aF8w4JRBbLBNwbBtc7qcpjyakUb3VDAeYLgM40FhoE8bprsqmtAi1O-BCTCtxiJ35I4DvVXymH5zmTwtRJFTm04ToIfd9RV4wuBJLFB6tEfttuBcB1zQ-A/s1600/01_Parameter+Sniffing+with+OR+issue.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="465" data-original-width="826" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbDetVS2k71BK22CksHYFb1aF8w4JRBbLBNwbBtc7qcpjyakUb3VDAeYLgM40FhoE8bprsqmtAi1O-BCTCtxiJ35I4DvVXymH5zmTwtRJFTm04ToIfd9RV4wuBJLFB6tEfttuBcB1zQ-A/s640/01_Parameter+Sniffing+with+OR+issue.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
與 Dev Team 討論，理解 Business 商務面的需求：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;輸入參數是 NULL&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;用於找回全部資料，並且額外顯示 資料表: Sales.SalesOrderDetail 的相關資訊。&lt;/li&gt;
&lt;li&gt;此為管理階層常用的報表。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;輸入參數是 特定值&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;是客戶於登入系統時要使用，不需要 資料表: Sales.SalesOrderDetail 的資料。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
兩個不同的需求，使用 OR 運算子整合在同一個 Stored Procedure 內。&lt;br /&gt;
經確認與討論後，決定改寫為兩隻符合各自需求的 Stored Procedure。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
01. 建立 2 隻符合各自需求的 Stored Procedure&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
GetSalesList_Only&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;輸入參數是 NULL&lt;/li&gt;
&lt;li&gt;WHERE (&lt;span style="color: blue;"&gt;@SalesOrderID IS NULL&lt;/span&gt;)&amp;nbsp;&lt;/li&gt;
&lt;li&gt;額外顯示 資料表: Sales.SalesOrderDetail 的相關資訊&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
GetSalesOrderID&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;輸入參數是 特定值&lt;/li&gt;
&lt;li&gt;WHERE &lt;span style="color: blue;"&gt;sd.SalesOrderID = @SalesOrderID&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;不需要 資料表: Sales.SalesOrderDetail 的資料:&amp;nbsp;&lt;span style="color: red;"&gt;sd.*&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure 81_Create 2 Procs for different purposes&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6zoz_PBb6St6Utlljo9gFVfpxPOVmcueVc8sfEH_4QlpvG905-9gKU5okdVH6ZFaOvtXFs0Cc4Rhpbr51ya2cqQfsNbpXJTszQEDKvctck7arXERYHdyBDsPo6bYFsIlAGyjUyZupdGs/s1600/81_Create+2+Procs+for+different+purposes.png" imageanchor="1"&gt;&lt;img border="0" height="448" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6zoz_PBb6St6Utlljo9gFVfpxPOVmcueVc8sfEH_4QlpvG905-9gKU5okdVH6ZFaOvtXFs0Cc4Rhpbr51ya2cqQfsNbpXJTszQEDKvctck7arXERYHdyBDsPo6bYFsIlAGyjUyZupdGs/s640/81_Create+2+Procs+for+different+purposes.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02.&amp;nbsp;執行 這兩 2 隻符合各自需求的 Stored Procedure&lt;br /&gt;
&lt;br /&gt;
分別輸入 GetSalesList_Only NULL 與 GetSalesOrderID 43659。&lt;br /&gt;
&lt;br /&gt;
GetSalesList_Only NULL:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;取回全部資料，回傳 118,744 rows，使用 Clustered Index Scan。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
GetSalesOrderID 43659&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;取回指定 SalesOrderID 的資料，回傳 12 rows。&lt;/li&gt;
&lt;li&gt;經 Query Optimizer 執行優化後，使用效率佳 Clustered Index &lt;span style="color: blue;"&gt;Seek&lt;/span&gt;。&lt;/li&gt;
&lt;li&gt;這是有提升執行效能的 Execution Plan。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure 82_EXEC_2 Procs&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiYMNgO0E2cfS2VEVpg75cXfMgfehK70VEXy4QeZfadKIjURCoUXytj3-xn_8n3v9YaWBb8hflNP2wc5Kr1rV5huilYfWEnwkFTA-9YYEwzCLnShyphenhyphenoXSAX77mIJkCxDL0mzfpbJGDGxP0/s1600/72_EXEC_2+Procs.png" imageanchor="1"&gt;&lt;img border="0" height="234" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiYMNgO0E2cfS2VEVpg75cXfMgfehK70VEXy4QeZfadKIjURCoUXytj3-xn_8n3v9YaWBb8hflNP2wc5Kr1rV5huilYfWEnwkFTA-9YYEwzCLnShyphenhyphenoXSAX77mIJkCxDL0mzfpbJGDGxP0/s640/72_EXEC_2+Procs.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 觀察 Execution Plan&lt;br /&gt;
&lt;br /&gt;
當執行 GetSalesList_Only NULL:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;使用 Clustered Index Scan。&lt;/li&gt;
&lt;li&gt;Actual Rows: 118,744。&lt;/li&gt;
&lt;li&gt;Est Rows: 116,323，這是 Estimated Number of Rows。&lt;/li&gt;
&lt;li&gt;Reads: 2,249，這是 Logical Reads。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
相比先前的解決方案，與使用 輸入參數 NULL 的 Execution Plan 都雷同。&lt;br /&gt;
&lt;br /&gt;
-- figure 83_Plan_Explorer&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjvt_Wa6Ly7SUiH2TR09kKLUglGW6s-kNot_xwKSnJjK2GYNp5NyW5Kf0iR7QgTy9xxKD3EkSXL1SBhJUiFN8TGqYynXVkB7LwM7rMUEWTUEz3tRjrYAtKInyXJzr8BSNrTw8oNUHBHSw/s1600/83_Plan_Explorer.png" imageanchor="1"&gt;&lt;img border="0" height="430" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjvt_Wa6Ly7SUiH2TR09kKLUglGW6s-kNot_xwKSnJjK2GYNp5NyW5Kf0iR7QgTy9xxKD3EkSXL1SBhJUiFN8TGqYynXVkB7LwM7rMUEWTUEz3tRjrYAtKInyXJzr8BSNrTw8oNUHBHSw/s640/83_Plan_Explorer.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure 84_Plan_Explorer&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBJiYp_FRDDG1fhIoWO9Xc_TvQ-ogrEEA99boijOYuO4aChQMKIE0XUlCk3qRd-HtVlJnPHpCA54l0Q6OJm9Bj3rCTEhXgJMbZxVlnZiTNSf92gliyDn21rVTjkxT0ASytq3Xmn3jxpZU/s1600/84_Plan_Explorer+.png" imageanchor="1"&gt;&lt;img border="0" height="430" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBJiYp_FRDDG1fhIoWO9Xc_TvQ-ogrEEA99boijOYuO4aChQMKIE0XUlCk3qRd-HtVlJnPHpCA54l0Q6OJm9Bj3rCTEhXgJMbZxVlnZiTNSf92gliyDn21rVTjkxT0ASytq3Xmn3jxpZU/s640/84_Plan_Explorer+.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
-- figure 85_Compute Scalar 1&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSz7SdEpKDWTeK3Jd7k_okh12GvnWAfR-GAtaAF00ypE-yZYMkI84VIoDq6p5jPI6OqJnKJKik_tp7eofNGtc3lACmM2u3yIS6gdQa4FgUuyjjXl69j0C9tFl6w7SMJ53dweUa6yvtPWM/s1600/85_Compute+Scalar+1.png" imageanchor="1"&gt;&lt;img border="0" height="224" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSz7SdEpKDWTeK3Jd7k_okh12GvnWAfR-GAtaAF00ypE-yZYMkI84VIoDq6p5jPI6OqJnKJKik_tp7eofNGtc3lACmM2u3yIS6gdQa4FgUuyjjXl69j0C9tFl6w7SMJ53dweUa6yvtPWM/s640/85_Compute+Scalar+1.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
-- figure 86_Compute Scalar 2&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXdCZrD0ilk_oeSUskSP4i5v6LZjyHE_6iaVmID_gytJlT-gqqEj_wdaLj29iGAvkD1JfQ3ziTuXSUqblt0a-peoKsGf0y5lu3f9DKmICIG6egiCeaUvlRSbzehSan0m_GjqQWPFUXlN8/s1600/86_Compute+Scalar+2.png" imageanchor="1"&gt;&lt;img border="0" height="224" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXdCZrD0ilk_oeSUskSP4i5v6LZjyHE_6iaVmID_gytJlT-gqqEj_wdaLj29iGAvkD1JfQ3ziTuXSUqblt0a-peoKsGf0y5lu3f9DKmICIG6egiCeaUvlRSbzehSan0m_GjqQWPFUXlN8/s640/86_Compute+Scalar+2.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;87_LineTotal_Data&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOTbi9k9M1MoXpkugz062Siq92BY6M875zBsBH9T2EQ0YjdS-9ZFAbbSgWuLmRT4sGGXJCbZkSXYF-Y8TvOsJBWqnlycLSWEZ6gQZJsOiEk8ZuJP9o32QJ6Z2UnGwIc_KhXbiiUia45Go/s1600/87_LineTotal_Data.png" imageanchor="1"&gt;&lt;img border="0" height="112" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOTbi9k9M1MoXpkugz062Siq92BY6M875zBsBH9T2EQ0YjdS-9ZFAbbSgWuLmRT4sGGXJCbZkSXYF-Y8TvOsJBWqnlycLSWEZ6gQZJsOiEk8ZuJP9o32QJ6Z2UnGwIc_KhXbiiUia45Go/s640/87_LineTotal_Data.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
04. 觀察 Execution Plan&lt;br /&gt;
&lt;br /&gt;
當執行 GetSalesOrderID 43659:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;使用 Clustered Index&amp;nbsp;&lt;span style="color: blue;"&gt;Seek&lt;/span&gt;。&lt;/li&gt;
&lt;li&gt;Actual Rows: 12。&lt;/li&gt;
&lt;li&gt;Est Rows: 12，這是 Estimated Number of Rows。精準符合 Actual Rows。&lt;/li&gt;
&lt;li&gt;Reads: 12，這是 Logical Reads。&lt;/li&gt;
&lt;li&gt;省去無需使用的 資料行&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;只需 3 個資料行：c.PersonID, sh.Freight, cc.CardType&lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;省去使用 &lt;/span&gt;Compute Scalar 運算子。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
相較先前的解決方案，這是 &lt;span style="color: blue;"&gt;執行效能最佳&amp;nbsp;&lt;/span&gt;的 Execution Plan !&lt;br /&gt;
&lt;br /&gt;
-- figure 88_Plan_Explorer&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBUT_UpwE03F3szVwrOkIyJgQ3DPxtzcI2KbBOuLeGbJRgdgUoPg2VKASvSDPT2W33P9ek8zbbuD4l-_jsKtrdLJ87wOpsAfZXhk3ekuh_WYfAIwPFVvYRadfvFLXcfyG8Efh8bkiT0QA/s1600/88_Plan_Explorer.png" imageanchor="1"&gt;&lt;img border="0" height="328" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBUT_UpwE03F3szVwrOkIyJgQ3DPxtzcI2KbBOuLeGbJRgdgUoPg2VKASvSDPT2W33P9ek8zbbuD4l-_jsKtrdLJ87wOpsAfZXhk3ekuh_WYfAIwPFVvYRadfvFLXcfyG8Efh8bkiT0QA/s640/88_Plan_Explorer.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Sample Code&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
20180821_Parameter_Sniffing_with_OR_Operator&lt;br /&gt;
&lt;a href="https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing"&gt;https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Reference&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
[Case Study] Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (1)&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or.html"&gt;http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
[Case Study] Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (2)&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or_23.html"&gt;http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or_23.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
[Case Study] Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (3)&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or_24.html"&gt;http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or_24.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
[Case Study] Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR &lt;a href="https://www.blogger.com/goog_1481343092"&gt;運算子 (4)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or_31.html"&gt;http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or_31.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
[Parameter Sniffing] Reuse bad execution plan and Recompile stored procedure, 重複使用效能差的 執行計劃 與 重新編譯 預存程序&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/parameter-sniffing-reuse-bad-execution.html"&gt;http://sharedderrick.blogspot.com/2018/08/parameter-sniffing-reuse-bad-execution.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Parameter Sniffing: Dynamic SQL, sp_executesql and EXEC (Parameter Sniffing 與 動態 SQL)&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/parameter-sniffing-dynamic-sql.html"&gt;http://sharedderrick.blogspot.com/2018/08/parameter-sniffing-dynamic-sql.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Compare "WITH RECOMPILE / sp_recompile" with "OPTION RECOMPILE"&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/02/sql-server-compare-with-recompile-with.html"&gt;http://sharedderrick.blogspot.com/2018/02/sql-server-compare-with-recompile-with.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Parameter Sniffing: Local Variable&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/01/sql-server-parameter-sniffing-local.html"&gt;http://sharedderrick.blogspot.com/2018/01/sql-server-parameter-sniffing-local.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Parameter Sniffing: OPTION OPTIMIZE FOR UNKNOWN&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/01/sql-server-parameter-sniffing-option_7.html"&gt;http://sharedderrick.blogspot.com/2018/01/sql-server-parameter-sniffing-option_7.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Parameter Sniffing: OPTION OPTIMIZE FOR UNKNOWN 2&lt;br /&gt;
&lt;div style="margin: 0px; text-indent: 0px;"&gt;
&lt;div style="color: black; font-family: &amp;quot;times new roman&amp;quot;; font-size: medium; font-style: normal; font-weight: 400; letter-spacing: normal; text-transform: none; white-space: normal; word-spacing: 0px;"&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/01/sql-server-parameter-sniffing-option_14.html"&gt;http://sharedderrick.blogspot.com/2018/01/sql-server-parameter-sniffing-option_14.html&lt;/a&gt;&lt;/div&gt;
&lt;div style="color: black; font-family: &amp;quot;times new roman&amp;quot;; font-size: medium; font-style: normal; font-weight: 400; letter-spacing: normal; text-transform: none; white-space: normal; word-spacing: 0px;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style="font-family: &amp;quot;times new roman&amp;quot;;"&gt;Ad hoc Query and Reuse - 重複使用&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;times new roman&amp;quot;;"&gt;&lt;a href="http://sharedderrick.blogspot.com/2017/11/sql-server-ad-hoc-query-and-reuse.html"&gt;http://sharedderrick.blogspot.com/2017/11/sql-server-ad-hoc-query-and-reuse.html&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Dynamic SQL, sp_executesql and EXEC (Parameter Sniffing 與 動態 SQL)&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/parameter-sniffing-dynamic-sql.html"&gt;http://sharedderrick.blogspot.com/2018/08/parameter-sniffing-dynamic-sql.html&lt;/a&gt;&lt;/div&gt;
</description><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7C1PEDXML0-OWg53o3d7q9omd6XPcX-1GmzAN3wOPvQOUc5NStcdrTSRWpSvOJL3UGOxN_Fvj03CdKyUXwZcevwKZekl2Zjd7bCkfkLX_pFihxC5fN2FmH4hmtQ1suu0Ul5vRl9FRX7M/s72-c/88_Plan_Explorer.png" width="72"/><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><title>[Case Study] Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (4)</title><link>http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or_31.html</link><category>Performance Tuning</category><category>SQL Server</category><author>noreply@blogger.com (DerrickLaLa)</author><pubDate>Fri, 31 Aug 2018 22:48:00 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1420955872914622499.post-6898358577325820751</guid><description>&lt;br /&gt;
延續前一篇文章：&lt;a href="http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or_24.html"&gt;[Case Study] Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (3)&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
使用 UNION ALL 或 IF ELSE 改寫 Stored Procedure&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;仍使用 Parameter Sniffing 機制，Reuse Execution Plan。&lt;/li&gt;
&lt;li&gt;讓 Query Optimizer 優化使用到更佳的索引，例如： Clustered Index Seek。&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;使用 IF ELSE，經判斷後，&lt;span style="color: blue;"&gt;僅&lt;/span&gt; 執行滿足 條件式 的 SQL Statement。&lt;/li&gt;
&lt;li&gt;但 UNION ALL 卻是執行&amp;nbsp;&lt;span style="color: red;"&gt;全部&amp;nbsp;&lt;/span&gt;的 SQL Statement，再組合起來回傳。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
繼續討論 Parameter Sniffing 的 因應之道：&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;使用 EXEC ... WITH RECOMPILE&lt;/li&gt;
&lt;li&gt;使用 sp_recompile&lt;/li&gt;
&lt;li&gt;修改 Stored Procedure，使用 Local Variables&lt;/li&gt;
&lt;li&gt;修改 Stored Procedure，使用 WITH RECOMPILE&lt;/li&gt;
&lt;li&gt;修改 Stored Procedure，使用 OPTION RECOMPILE&lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;改寫 Stored Procedure，使用 UNION ALL&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;改寫 Stored Procedure，使用 IF ELSE&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;改寫 Stored Procedure，使用 Dynamic SQL: EXEC&lt;/li&gt;
&lt;li&gt;修改 Stored Procedure，使用 Dynamic SQL: sp_executesql&lt;/li&gt;
&lt;li&gt;因應需求，分別建立 Stored Procedure&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Parameter Sniffing with OR Operator issue,&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;當 Parameter Sniffing 遇上 OR 運算子(4)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
回顧&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;條件式:&amp;nbsp; WHERE (@SalesOrderID IS NULL OR sd.SalesOrderID = @SalesOrderID)&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3bsIAtaOHWvOKYS2RWh5LDYE1O6UZf9Yh4u0L6s8k9PpFSRBL4fFq6-dYHF5QnJAxwVymWlk3zSV3tvtPxsDFhRDo9WPsmF2vrYs7Tl3HgWHKUw1s9u55aoUeYmYgtzzpRy-HAismQpg/s1600/01_Parameter+Sniffing+with+OR+issue.png" imageanchor="1"&gt;&lt;img border="0" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3bsIAtaOHWvOKYS2RWh5LDYE1O6UZf9Yh4u0L6s8k9PpFSRBL4fFq6-dYHF5QnJAxwVymWlk3zSV3tvtPxsDFhRDo9WPsmF2vrYs7Tl3HgWHKUw1s9u55aoUeYmYgtzzpRy-HAismQpg/s640/01_Parameter+Sniffing+with+OR+issue.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
以 Index 使用策略來看，已知&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;@SalesOrderID IS NULL，使用 Index Scan。&lt;/li&gt;
&lt;li&gt;sd.SalesOrderID = @SalesOrderID，使用 Index Seek。&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
今藉由 OR 運算子，整合在同一個 Stored Procedure。&lt;br /&gt;
&lt;div&gt;
若硬是要找出一個 Index 可以符合這兩者的效能需求，這該怎麼辦呢?&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: purple; font-size: large;"&gt;燃起 程式魂&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: purple; font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="color: blue;"&gt;跳脫框架，改寫 條件式邏輯!&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;6. 改寫 Stored Procedure，使用 UNION ALL&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
此處使用 改寫，是因為要對 條件式 進行改寫，而非先前僅是修改 編譯參數。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
說明：&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;使用 Parameter Sniffing 機制，Reuse Execution Plan。&lt;/li&gt;
&lt;li&gt;UNION ALL&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;每次執行 Stored Procedure，都必須要分別執行全部 SQL Statement 的 WHERE 條件式之判斷。&lt;/li&gt;
&lt;li&gt;再利用 UNION ALL 將結果組合起來回傳。這勢必多耗用系統資源。&lt;/li&gt;
&lt;li&gt;Execution Plan 相對複雜，Subtree Cost 已失真。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;對比 Local Variables，改寫為 UNION ALL：&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;讓 Query Optimizer 優化使用到更佳的索引，例如： Clustered Index Seek。&lt;/li&gt;
&lt;li&gt;沒有使用到效率差的 Clustered Index Scan。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;對比 WITH RECOMPILE 或 OPTION RECOMPILE，改寫為 UNION ALL：&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;使用 Parameter Sniffing 機制，Reuse Execution Plan，沒有額外重新編譯。&lt;/li&gt;
&lt;li&gt;相形之下，會比 WITH RECOMPILE 或 OPTION RECOMPILE 更適合於 每秒 都要大量執行 或 同時間會大量執行 的程式 等情境。&lt;/li&gt;
&lt;li&gt;但若有大量 UNION ALL 卻會耗用過多資源，需要進一步的測試與評估。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
注意事項：&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;修改 Stored Procedure 程式碼，牽扯版本問題。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;需要與 SQL Developer 人員溝通討論。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
01. 建立使用 &lt;span style="color: blue;"&gt;UNION ALL&amp;nbsp;&lt;/span&gt;的 Stored Procedure。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;必須修改原來的程式碼。&lt;/li&gt;
&lt;li&gt;將 條件式 OR 運算子，改寫為 多段 SELECT statement，再額外使用 UNION ALL&amp;nbsp;結合起來。&lt;/li&gt;
&lt;li&gt;換句話說&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;輸入 任何 參數值，都必須要分別執行全部 SQL Statement 的 WHERE 條件式之判斷。&lt;/li&gt;
&lt;li&gt;再利用 UNION ALL 將結果組合起來回傳。&lt;/li&gt;
&lt;li&gt;增加執行成本。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;若有多段 SELECT statement，會增加維護的複雜度。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure 61_ALTER Proc UNION ALL&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0NxrW9AX9paXBadlNjRBb0XkleQp18qGYtV9u-k_0feDdw89VgEiXratWATrNiDC1Xxzo8Cjo-TyLgL37RWByQ9ldLqMWJzD2C5g2xZ3xqKufN0sn1jFlJXIYMHiP5lC7nXTgrDsdrec/s1600/71_ALTER+Proc+UNION+ALL.png" imageanchor="1"&gt;&lt;img border="0" height="506" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0NxrW9AX9paXBadlNjRBb0XkleQp18qGYtV9u-k_0feDdw89VgEiXratWATrNiDC1Xxzo8Cjo-TyLgL37RWByQ9ldLqMWJzD2C5g2xZ3xqKufN0sn1jFlJXIYMHiP5lC7nXTgrDsdrec/s640/71_ALTER+Proc+UNION+ALL.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 執行 使用 UNION ALL 的 Stored Procedure。&lt;br /&gt;
&lt;br /&gt;
分別輸入 NULL 與 43659。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;當輸入參數是&amp;nbsp;NULL:&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;取回全部資料，回傳 118,744 rows，使用 Clustered Index Scan。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;當輸入參數是&amp;nbsp;43659:&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;取回指定 SalesOrderID 的資料，回傳 12 rows。&lt;/li&gt;
&lt;li&gt;經 Query Optimizer 執行優化後，使用 Clustered Index &lt;span style="color: blue;"&gt;Seek&lt;/span&gt;。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;沒有使用到效率差的 Clustered Index Scan。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;這是有提升執行效能的 Execution Plan。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
似乎美好，進一步來檢視&amp;nbsp;Execution Plan。&lt;br /&gt;
&lt;br /&gt;
-- figure 62_EXEC_Proc UNION ALL&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeh2n-tCL58MkHiImVx3ElT76SLqfsYPgAtWhNB1xkgJQ5rX_i8kBrpMu81yMfphH9glLhw7RVjrXutynbKNVrqr7PbMRVSxdiHcWZl_ymAt5Sim9HbOnKkdwwSGGr4jjLWxpPbsrpqN4/s1600/72_EXEC_Proc+UNION+ALL.png" imageanchor="1"&gt;&lt;img border="0" height="236" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeh2n-tCL58MkHiImVx3ElT76SLqfsYPgAtWhNB1xkgJQ5rX_i8kBrpMu81yMfphH9glLhw7RVjrXutynbKNVrqr7PbMRVSxdiHcWZl_ymAt5Sim9HbOnKkdwwSGGr4jjLWxpPbsrpqN4/s640/72_EXEC_Proc+UNION+ALL.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03.&amp;nbsp;觀察 Execution Plan:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;複雜的 Execution Plan&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;使用 &lt;b&gt;&lt;span style="color: blue;"&gt;Concatenation 運算子&lt;/span&gt;&lt;/b&gt;，結合多段 SQL Statement 的 Execution Plan。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;將 輸入參數為 NULL 與 輸入參數 43659 的兩份 Execution Plan，結合成一大份 Execution Plan。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;換句話說，輸入 任何 參數值，都必須要分別執行全部 SQL Statement 的 WHERE 條件式之判斷。&lt;/li&gt;
&lt;li&gt;再利用 UNION ALL 將結果組合起來回傳。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
採用 Parameter Sniffing 機制&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
由於是各自獨立的 SQL statement，再使用 UNION ALL 結合再一起，因此，Query Optimizer 可以為各個 SQL statement 選擇更加合適的 Index。&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;但仍然採取 Parameter Sniffing 機制，重複使用 Execution Plan。&lt;/li&gt;
&lt;li&gt;潛藏著誤用 Execution Plan，導致效能更糟的問題。&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
-- figure 63_Complex Execution Plan&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwCQDFz0-nO_CXvs_nWLCjOq_bIhfcaO_k-sY3ChSaFOdlg3MSJ66xUcATEySNjsOqOYvsm3eJ3pAf3Z0rUqhsEQVIGKTnh6QXqWvoDnpZBbEqa8Hj9jDJ95MkQVjg-mpzE90S1aesH-w/s1600/73_Complex+Execution+Plan.png" imageanchor="1"&gt;&lt;img border="0" height="232" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwCQDFz0-nO_CXvs_nWLCjOq_bIhfcaO_k-sY3ChSaFOdlg3MSJ66xUcATEySNjsOqOYvsm3eJ3pAf3Z0rUqhsEQVIGKTnh6QXqWvoDnpZBbEqa8Hj9jDJ95MkQVjg-mpzE90S1aesH-w/s640/73_Complex+Execution+Plan.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
04. 觀察 Execution Plan:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;整體的 Estimated Subtree Cost是：5.03934。&lt;/li&gt;
&lt;li&gt;已失真的 Subtree Cost&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;結合多份 SQL statement，所產生的 Execution Plan。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure 64_Complex Execution Plan&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIVhPKu4Km7EtP6kk_52Sml6Y7cOxIozrpOjAUzkgdzLpr7B5wVStX9osxtPA44B0pKOBMenmQHSgtFl8tLkbem8qD0tiMMSOWxXZl5KozUVmFceLhJ9nkh0OXoskoEEW-PVIFQ-kE8IE/s1600/74_Complex+Execution+Plan.png" imageanchor="1"&gt;&lt;img border="0" height="408" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIVhPKu4Km7EtP6kk_52Sml6Y7cOxIozrpOjAUzkgdzLpr7B5wVStX9osxtPA44B0pKOBMenmQHSgtFl8tLkbem8qD0tiMMSOWxXZl5KozUVmFceLhJ9nkh0OXoskoEEW-PVIFQ-kE8IE/s640/74_Complex+Execution+Plan.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
05.&amp;nbsp;綜合觀察 1&lt;br /&gt;
&lt;br /&gt;
當輸入參數是 NULL&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;使用 Clustered Index Scan。&lt;/li&gt;
&lt;li&gt;Actual Rows: 118,744。&lt;/li&gt;
&lt;li&gt;Est Rows: 116,323，這是 Estimated Number of Rows。&lt;/li&gt;
&lt;li&gt;Reads: &lt;span style="color: red;"&gt;2,249&lt;/span&gt;，這是 Logical Reads。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure 65_Plan_Explorer&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3B79lH7KZdSPwJO-z6Vzy-Zk7ySfZo-dVlnfnFdCbLA7lnO1iYN59CpJc8Zq6g6xUbgDBMrPDKGAFnGl3lXSQGdwIYVXMyTGdwuD6nCipImdp8igqnTEKCUheapTENLedDhgQ9nNZxlk/s1600/75_Plan_Explorer.png" imageanchor="1"&gt;&lt;img border="0" height="364" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3B79lH7KZdSPwJO-z6Vzy-Zk7ySfZo-dVlnfnFdCbLA7lnO1iYN59CpJc8Zq6g6xUbgDBMrPDKGAFnGl3lXSQGdwIYVXMyTGdwuD6nCipImdp8igqnTEKCUheapTENLedDhgQ9nNZxlk/s640/75_Plan_Explorer.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
05.&amp;nbsp;綜合觀察 2&lt;br /&gt;
&lt;br /&gt;
當輸入參數是 43659&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;使用 Clustered Index Seek。&lt;/li&gt;
&lt;li&gt;Actual Rows: 12。&lt;/li&gt;
&lt;li&gt;Est Rows: 116,323，這是 Estimated Number of Rows。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;評估失真。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;Reads: &lt;span style="color: red;"&gt;372&lt;/span&gt;，這是 Logical Reads。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure 66_Plan_Explorer&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjySGW3UMtFrYmfp9cLYlpSKSZjjgLxTx8gBUbgfBSCRF2XuAWZeDck5v7A4F94_tf5zBakcd59d4w71ZQC6HIYa0sI5fePo-srWAXd-UuhEPgSGzpGuXJEZIksb8K7wWklAgFY2CMWYOw/s1600/76_Plan_Explorer.png" imageanchor="1"&gt;&lt;img border="0" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjySGW3UMtFrYmfp9cLYlpSKSZjjgLxTx8gBUbgfBSCRF2XuAWZeDck5v7A4F94_tf5zBakcd59d4w71ZQC6HIYa0sI5fePo-srWAXd-UuhEPgSGzpGuXJEZIksb8K7wWklAgFY2CMWYOw/s640/76_Plan_Explorer.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;7. 改寫 Stored Procedure，使用 IF ELSE&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
此處使用 改寫，是因為要對 條件式 進行改寫，而非先前僅是修改 編譯參數。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
說明：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;使用 Parameter Sniffing 機制，Reuse Execution Plan。&lt;/li&gt;
&lt;li&gt;使用 IF ELSE&amp;nbsp;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;經判斷後，僅執行 滿足 條件式 的 Transact-SQL 陳述式。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;對比 Local Variables，改寫為 IF ELSE ：&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;讓 Query Optimizer 優化使用到更佳的索引，例如： Clustered Index Seek。&lt;/li&gt;
&lt;li&gt;沒有使用到效率差的 Clustered Index Scan。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;對比 WITH RECOMPILE 或 OPTION RECOMPILE，改寫為 IF ELSE：&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;使用 Parameter Sniffing 機制，Reuse Execution Plan，沒有額外重新編譯。&lt;/li&gt;
&lt;li&gt;相形之下，會比 WITH RECOMPILE 或 OPTION RECOMPILE 更適合於 每秒 都要大量執行 或 同時間會大量執行 的程式 等情境。&lt;/li&gt;
&lt;li&gt;但若 IF ELSE 是複雜邏輯運算，則應評估與測試。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;對比 UNION ALL，改寫為 IF ELSE：&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;使用 IF ELSE 流程控制語言，經判斷後，&amp;nbsp;&lt;span style="color: blue;"&gt;僅&lt;/span&gt;執行滿足 條件式 的 Transact-SQL 陳述式；&lt;/li&gt;
&lt;li&gt;但 UNION ALL 卻是執行全部的 Transact-SQL 陳述式，再組合起來回傳。&lt;/li&gt;
&lt;li&gt;若有多段 SELECT statement 需要使用到 IF ELSE&amp;nbsp;結合，則會增加維護的複雜度。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
說明：&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;修改 Stored Procedure 程式碼，牽扯版本問題。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;需要與 SQL Developer 人員溝通討論。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
01. 建立使用 IF ELSE 的 Stored Procedure。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;必須修改原來的程式碼。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
使用 IF ELSE 流程控制語言，改寫為：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;如果 IF 關鍵字的條件獲得滿足，就會執行在 IF 關鍵字及其條件之後的 Transact-SQL 陳述式：布林運算式會傳回 TRUE。&lt;/li&gt;
&lt;li&gt;選擇性的 ELSE 關鍵字導入了另一個在 IF 條件未獲滿足時所執行的 Transact-SQL 陳述式：布林運算式會傳回 FALSE。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
與&amp;nbsp;UNION ALL 不同在於&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;使用 IF ELSE 流程控制語言，經判斷後，&amp;nbsp;&lt;span style="color: blue;"&gt;僅執行&lt;/span&gt;滿足 條件式 的 Transact-SQL 陳述式；&lt;/li&gt;
&lt;li&gt;但 UNION ALL 卻是執行全部的 Transact-SQL 陳述式，再組合起來回傳。&lt;/li&gt;
&lt;li&gt;若有多段 SELECT statement 需要使用到 UNION ALL&amp;nbsp;結合，則會增加維護的複雜度。&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
-- figure 71_ALTER Proc IF ELSE&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZIjYZhWsCrzkroV9ERWwuJ66ms78bpcTwjKkHQB0vgPig72CPtVtI7Ng1Q3I9x5V_osU50irNZZW0AGWgXokwgcxFAZ-g29CxnfpSKfZZ2aCjD-kPppJZaidvffJ5Jjo9euJ-gzSEUko/s1600/61_ALTER+Proc+IF+ELSE.png" imageanchor="1"&gt;&lt;img border="0" height="570" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZIjYZhWsCrzkroV9ERWwuJ66ms78bpcTwjKkHQB0vgPig72CPtVtI7Ng1Q3I9x5V_osU50irNZZW0AGWgXokwgcxFAZ-g29CxnfpSKfZZ2aCjD-kPppJZaidvffJ5Jjo9euJ-gzSEUko/s640/61_ALTER+Proc+IF+ELSE.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 執行 使用 IF ELSE&amp;nbsp;的 Stored Procedure。&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
分別輸入 NULL 與 43659。&lt;br /&gt;
&lt;br /&gt;
當輸入參數是 NULL:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;取回全部資料，回傳 118,744 rows，使用 Clustered Index Scan。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
當輸入參數是 43659:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;取回指定 SalesOrderID 的資料，回傳 12 rows。&lt;/li&gt;
&lt;li&gt;經 Query Optimizer 執行優化後，使用 Clustered Index &lt;span style="color: blue;"&gt;Seek&lt;/span&gt;。&lt;/li&gt;
&lt;li&gt;沒有使用到效率差的 Clustered Index Scan。&lt;/li&gt;
&lt;li&gt;這是有提升執行效能的 Execution Plan。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;div&gt;
似乎美好，進一步來檢視 Execution Plan。&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
-- figure 72_EXEC_Proc IF ELSE&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1CXUZfVgklNvqs4p-llMDjJx5nzCbC1Vl6BibEubkuIOSNsrzTgN8arrdt9QivNmhnF_N3nyha70PXPDTt0veFNmHjNuYpwjGRQ4SjK9fkpLbxQOKGAjl87EVYDC0XtVdjARGqAD84Lg/s1600/62_EXEC_Proc+IF+ELSE.png" imageanchor="1"&gt;&lt;img border="0" height="236" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1CXUZfVgklNvqs4p-llMDjJx5nzCbC1Vl6BibEubkuIOSNsrzTgN8arrdt9QivNmhnF_N3nyha70PXPDTt0veFNmHjNuYpwjGRQ4SjK9fkpLbxQOKGAjl87EVYDC0XtVdjARGqAD84Lg/s640/62_EXEC_Proc+IF+ELSE.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
03.&amp;nbsp;觀察 Execution Plan:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
以&amp;nbsp;EXEC GetSalesList_IF 43659 為例&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;經判斷後，僅執行該 SQL Query 的 Execution Plan&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;與 UNION ALL 比較起來， 使用 IF ELSE 的 Execution Plan 是簡潔的。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;使用 IF ELSE 流程控制語言，經判斷後，&amp;nbsp;僅執行滿足 條件式 的 Transact-SQL 陳述式。&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
採用 Parameter Sniffing 機制&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;使用 IF ELSE 流程控制語言 僅執行滿足 條件式 的 Transact-SQL 陳述式，因此，Query Optimizer 可以為各個 SQL statement 選擇更加合適的 Index。&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div style="-webkit-text-stroke-width: 0px; color: black; font-family: &amp;quot;Times New Roman&amp;quot;; font-size: medium; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"&gt;
&lt;ul&gt;
&lt;li&gt;但仍然採取 Parameter Sniffing 機制，重複使用 Execution Plan。&lt;/li&gt;
&lt;li&gt;潛藏著誤用 Execution Plan，導致效能更糟的問題。&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
當輸入參數是 43659&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;使用 Clustered Index Seek。&lt;/li&gt;
&lt;li&gt;Actual Rows: 12。&lt;/li&gt;
&lt;li&gt;Est Rows: 1，這是 Estimated Number of Rows。&lt;/li&gt;
&lt;li&gt;Reads: &lt;span style="color: blue;"&gt;10&lt;/span&gt;，這是 Logical Reads。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;對比使用 UNION ALL，Reads 是 &lt;span style="color: red;"&gt;372&lt;/span&gt;，UNION ALL 使用更多的 Logical Reads。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure 73_Plan_Explorer&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkeSDHPJlq1hyUaLiFXnwW8vGcnUuhFI1jbFDWdOxXzGMMJ5xMY8E5YIHjEYc-OvLq5W2F3w877MHtAuZXS-vsH87tn938JihxI77FR58LUUZcS0BINqChFTen8whOY0oNANpkUMpK3UI/s1600/63_Plan_Explorer.png" imageanchor="1"&gt;&lt;img border="0" height="398" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkeSDHPJlq1hyUaLiFXnwW8vGcnUuhFI1jbFDWdOxXzGMMJ5xMY8E5YIHjEYc-OvLq5W2F3w877MHtAuZXS-vsH87tn938JihxI77FR58LUUZcS0BINqChFTen8whOY0oNANpkUMpK3UI/s640/63_Plan_Explorer.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
使用到 Compute Scalar 運算子，這是因為有使用 Computed Column(計算資料行): LineTotal。&lt;br /&gt;
&lt;br /&gt;
[[AdventureWorks2014].[Sales].[SalesOrderDetail].LineTotal] = Scalar Operator(isnull(CONVERT_IMPLICIT(numeric(19,4),[AdventureWorks2014].[Sales].[SalesOrderDetail].[UnitPrice] as [sd].[UnitPrice],0)*((1.0)-CONVERT_IMPLICIT(numeric(19,4),[AdventureWorks2014].[Sales].[SalesOrderDetail].[UnitPriceDiscount] as [sd].[UnitPriceDiscount],0))*CONVERT_IMPLICIT(numeric(5,0),[AdventureWorks2014].[Sales].[SalesOrderDetail].[OrderQty] as [sd].[OrderQty],0),(0.000000)))&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;111_Computed Column_LineTotal&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHX8fluvQtNkUVjo4CwTXo4cKsWLx6JMJ_nNLincQFLwO1gD5mueylIHwlm3po3gmEu8YRvXmD9Dugq9bsGo8LDz7jCT2BLutCt6ryCjljzGXmmiUkqrh45CwPOFHj-PKzhpOk2NO9He8/s1600/111_Computed+Column_LineTotal.png" imageanchor="1"&gt;&lt;img border="0" height="248" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHX8fluvQtNkUVjo4CwTXo4cKsWLx6JMJ_nNLincQFLwO1gD5mueylIHwlm3po3gmEu8YRvXmD9Dugq9bsGo8LDz7jCT2BLutCt6ryCjljzGXmmiUkqrh45CwPOFHj-PKzhpOk2NO9He8/s640/111_Computed+Column_LineTotal.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure 112_Computed Column_LineTotal&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnGCdVbSo5K8Q3sV3FU4nnUwYmMh7NefFuG66JPkf_J-QiAMyZTp2lZZY7AFxyOYSQ4gdLYGiMiP34cuUlYxW8-2Z4SNeLCNQ85A7yxrJlgDIMxt4zBvQrESFBGoa72NaOLQ31q1tS7Ow/s1600/112_Computed+Column_LineTotal.png" imageanchor="1"&gt;&lt;img border="0" height="624" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnGCdVbSo5K8Q3sV3FU4nnUwYmMh7NefFuG66JPkf_J-QiAMyZTp2lZZY7AFxyOYSQ4gdLYGiMiP34cuUlYxW8-2Z4SNeLCNQ85A7yxrJlgDIMxt4zBvQrESFBGoa72NaOLQ31q1tS7Ow/s640/112_Computed+Column_LineTotal.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure 113_Computed Column_LineTotal&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiy7H5FY5b3l1AqoBQVFfSpUb1W_Vc1Ui7KWIGyK9HX2_Srd2H_mPXhyAOvP_FdmCbMtPiRYiQ2eEFZsbFr32ilv1s9y4DWmjTDq5c7QsGvVa95IAZWFEICGUkeYBrtl8F7XVmHxeOCSbA/s1600/113_Computed+Column_LineTotal.png" imageanchor="1"&gt;&lt;img border="0" height="542" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiy7H5FY5b3l1AqoBQVFfSpUb1W_Vc1Ui7KWIGyK9HX2_Srd2H_mPXhyAOvP_FdmCbMtPiRYiQ2eEFZsbFr32ilv1s9y4DWmjTDq5c7QsGvVa95IAZWFEICGUkeYBrtl8F7XVmHxeOCSbA/s640/113_Computed+Column_LineTotal.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
04. 觀察 Execution Plan:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Actual Rows: 12&lt;/li&gt;
&lt;li&gt;Estimated Rows: 1&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
些微的落差。&lt;br /&gt;
&lt;br /&gt;
-- figure 74_Plan_Explorer&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfR6rpDxBeuaxROhJi5dAVU7tmpldyMZS8G8pVgqbAjkOBnOcJmbq_XclR0Bh_HridkK7cTu19XKQWZzBJg0V612WNgEvzSTxfOKlXOhwCg4ueOBjReUFglYkXf4LreERshc01c8IzFaA/s1600/64_Plan_Explorer.png" imageanchor="1"&gt;&lt;img border="0" height="482" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfR6rpDxBeuaxROhJi5dAVU7tmpldyMZS8G8pVgqbAjkOBnOcJmbq_XclR0Bh_HridkK7cTu19XKQWZzBJg0V612WNgEvzSTxfOKlXOhwCg4ueOBjReUFglYkXf4LreERshc01c8IzFaA/s640/64_Plan_Explorer.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Sample Code&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
20180821_Parameter_Sniffing_with_OR_Operator&lt;br /&gt;
&lt;a href="https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing"&gt;https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Reference&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
[Case Study] Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (1)&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or.html"&gt;http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
[Case Study] Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (2)&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or_23.html"&gt;http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or_23.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
[Case Study] Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (3)&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or_24.html"&gt;http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or_24.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
[Parameter Sniffing] Reuse bad execution plan and Recompile stored procedure, 重複使用效能差的 執行計劃 與 重新編譯 預存程序&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/parameter-sniffing-reuse-bad-execution.html"&gt;http://sharedderrick.blogspot.com/2018/08/parameter-sniffing-reuse-bad-execution.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Parameter Sniffing: Dynamic SQL, sp_executesql and EXEC (Parameter Sniffing 與 動態 SQL)&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/parameter-sniffing-dynamic-sql.html"&gt;http://sharedderrick.blogspot.com/2018/08/parameter-sniffing-dynamic-sql.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Compare "WITH RECOMPILE / sp_recompile" with "OPTION RECOMPILE"&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/02/sql-server-compare-with-recompile-with.html"&gt;http://sharedderrick.blogspot.com/2018/02/sql-server-compare-with-recompile-with.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Parameter Sniffing: Local Variable&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/01/sql-server-parameter-sniffing-local.html"&gt;http://sharedderrick.blogspot.com/2018/01/sql-server-parameter-sniffing-local.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Parameter Sniffing: OPTION OPTIMIZE FOR UNKNOWN&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/01/sql-server-parameter-sniffing-option_7.html"&gt;http://sharedderrick.blogspot.com/2018/01/sql-server-parameter-sniffing-option_7.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Parameter Sniffing: OPTION OPTIMIZE FOR UNKNOWN 2&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/01/sql-server-parameter-sniffing-option_14.html"&gt;http://sharedderrick.blogspot.com/2018/01/sql-server-parameter-sniffing-option_14.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Showplan Operator of the Week – Compute Scalar&lt;br /&gt;
&lt;a href="https://www.red-gate.com/simple-talk/sql/learn-sql-server/showplan-operator-of-the-week-compute-scalar/"&gt;https://www.red-gate.com/simple-talk/sql/learn-sql-server/showplan-operator-of-the-week-compute-scalar/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Showplan Operator of the Week – Concatenation&lt;br /&gt;
&lt;a href="https://www.red-gate.com/simple-talk/sql/learn-sql-server/showplan-operator-of-the-week---concatenation/"&gt;https://www.red-gate.com/simple-talk/sql/learn-sql-server/showplan-operator-of-the-week---concatenation/&lt;/a&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
</description><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3bsIAtaOHWvOKYS2RWh5LDYE1O6UZf9Yh4u0L6s8k9PpFSRBL4fFq6-dYHF5QnJAxwVymWlk3zSV3tvtPxsDFhRDo9WPsmF2vrYs7Tl3HgWHKUw1s9u55aoUeYmYgtzzpRy-HAismQpg/s72-c/01_Parameter+Sniffing+with+OR+issue.png" width="72"/><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><title>[Parameter Sniffing] Reuse bad execution plan and Recompile stored procedure, 重複使用效能差的 執行計劃 與 重新編譯 預存程序</title><link>http://sharedderrick.blogspot.com/2018/08/parameter-sniffing-reuse-bad-execution.html</link><category>Performance Tuning</category><category>SQL Server</category><author>noreply@blogger.com (DerrickLaLa)</author><pubDate>Sun, 26 Aug 2018 16:55:00 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1420955872914622499.post-5828210263205172630</guid><description>&lt;br /&gt;
曾經，遇見過 Parameter Sniffing 副作用的處理方式：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;只能採用&amp;nbsp; "Local Variables / OPTIMIZE FOR UNKNOWN"。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
強調 重新編譯 Stored Procedure 對於 資源耗用與影響。&lt;br /&gt;
&lt;br /&gt;
這是不合理的作法，缺少了對於 資料特性、存取資料量、執行頻率、Index、Statistics等角度考量，也忽視改寫 T-SQL 優化效能的可行性。&lt;br /&gt;
&lt;br /&gt;
一昧使用 "Local Variables / OPTIMIZE FOR UNKNOWN" 機制，或許，節省了開發時程 或 管控方便，但卻落得 Stored Procedure 執行效能不佳的問題!&lt;br /&gt;
&lt;br /&gt;
本案例，將以 "重複使用 效能差的 Execution Plan" 與 "重新編譯 Stored Procedure" 的整體執行效能差異來對照。&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzgK3G1vLXrH_hneMFvzos6RDyx86KZYSyCMWHHuprdWo_GCjd3x1rZ4wKAMU79Y4ry3XlTkIHT8Y4KtBJ2jcNAtpKgmzpkKhszdlJpi0s6Mw_i_6Pw9BsL7qK-7Rzym4XkjD_Fq2kS_c/s1600/12_Compare_ComileTime_CPU.png" imageanchor="1"&gt;&lt;img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzgK3G1vLXrH_hneMFvzos6RDyx86KZYSyCMWHHuprdWo_GCjd3x1rZ4wKAMU79Y4ry3XlTkIHT8Y4KtBJ2jcNAtpKgmzpkKhszdlJpi0s6Mw_i_6Pw9BsL7qK-7Rzym4XkjD_Fq2kS_c/s640/12_Compare_ComileTime_CPU.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;[Parameter Sniffing]&amp;nbsp;Reuse bad execution plan and Recompile stored procedure.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;重複使用效能差的 執行計劃 與 重新編譯 預存程序&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
01.&amp;nbsp;使用範例 Parameter Sniffing 與 OR 運算子，請參考以下文章：&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or.html"&gt;Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (1)&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
條件式:&amp;nbsp; WHERE (@SalesOrderID IS NULL&amp;nbsp;&lt;span style="color: blue;"&gt;OR&lt;/span&gt;&amp;nbsp;sd.SalesOrderID = @SalesOrderID)&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;@SalesOrderID IS NULL: 當 @SalesOrderID 是 NULL 時，取回全部的資料，回傳 118,744 rows。&lt;/li&gt;
&lt;li&gt;sd.SalesOrderID = @SalesOrderID: 取回 指定的 SalesOrderID 的 資料，回傳 12 rows。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
以 Index 使用策略來看：&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;這兩個條件式，應該是使用不同的 Index 存取方式，例如：Index&amp;nbsp;&lt;span style="color: red;"&gt;Scan&lt;/span&gt;、Index&amp;nbsp;&lt;span style="color: blue;"&gt;Seek&amp;nbsp;&lt;/span&gt;等。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;00_Parameter Sniffing with OR issue&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFRVlNF6nivqz86ul3VUGei_F_8JlBvS0apAuGV9F8YF7LU2iROunSVe0mAwWLSMwgAcMis2hyphenhyphenLHAiNL4OpXOi36IevMNtIMtHATNXXLZoQQzmwkeNOTrlWaQKrZnrGhyphenhyphenFTmIrY9yQPFU/s1600/01_Parameter+Sniffing+with+OR+issue.png" imageanchor="1"&gt;&lt;img border="0" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFRVlNF6nivqz86ul3VUGei_F_8JlBvS0apAuGV9F8YF7LU2iROunSVe0mAwWLSMwgAcMis2hyphenhyphenLHAiNL4OpXOi36IevMNtIMtHATNXXLZoQQzmwkeNOTrlWaQKrZnrGhyphenhyphenFTmIrY9yQPFU/s640/01_Parameter+Sniffing+with+OR+issue.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 執行此 Stored Procedure: dbo.GetSalesList。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;1st&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;使用 sp_recompile，重新編譯。&lt;/li&gt;
&lt;li&gt;輸入參數 NULL。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;2nd&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;因&amp;nbsp;Parameter Sniffing 發揮功效，重複使用 Execution Plan。&lt;/li&gt;
&lt;li&gt;誤用到效能差的 Execution Plan: Clustered Index&amp;nbsp;&lt;span style="color: red;"&gt;Scan&lt;/span&gt;。&lt;/li&gt;
&lt;li&gt;輸入參數&amp;nbsp;43659。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;3rd&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;再度 使用 sp_recompile，重新編譯。&lt;/li&gt;
&lt;li&gt;使用效能佳的 Execution Plan: Clustered Index&amp;nbsp;&lt;span style="color: blue;"&gt;Seek&lt;/span&gt;。&lt;/li&gt;
&lt;li&gt;輸入 NULL 與 43659。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;br /&gt;
-- figure&amp;nbsp;11_Parameter Sniffing_sp_recompile_Exec_Proc&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEE7Zt6HvfadVnGOX-KyblDCR1A6OHAJWkMyVvyimTr2pMxhRzJfwhXu5PzK51IB3izSop22HQeIF_V4JqiqgxAUS3lSjCAO8jh0HTtqQskvDGiK2pUvBhD8OsyKVlojzQTNJmhlI_ZBs/s1600/11_Parameter+Sniffing_sp_recompile_Exec_Proc.png" imageanchor="1"&gt;&lt;img border="0" height="390" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEE7Zt6HvfadVnGOX-KyblDCR1A6OHAJWkMyVvyimTr2pMxhRzJfwhXu5PzK51IB3izSop22HQeIF_V4JqiqgxAUS3lSjCAO8jh0HTtqQskvDGiK2pUvBhD8OsyKVlojzQTNJmhlI_ZBs/s640/11_Parameter+Sniffing_sp_recompile_Exec_Proc.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03.&amp;nbsp;使用 DMV 查詢 記憶體 Cache 區，檢視 Performance Data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;22_Compare_ComileTime_CPU&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiJ_68ivAEovqMznf3zEQR8NSTc1aVNydCMq_DvtJkh56RS07t1Te5xyKRCRVanf9pkpS3qk7qYKldKff_hNdHluu8Xc2sSHk76l3kHNpcwjUYcZxtH05qNLWMw0dRschmbn7vgDzW5dk/s1600/12_Compare_ComileTime_CPU.png" imageanchor="1"&gt;&lt;img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiJ_68ivAEovqMznf3zEQR8NSTc1aVNydCMq_DvtJkh56RS07t1Te5xyKRCRVanf9pkpS3qk7qYKldKff_hNdHluu8Xc2sSHk76l3kHNpcwjUYcZxtH05qNLWMw0dRschmbn7vgDzW5dk/s640/12_Compare_ComileTime_CPU.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;table border="1" cellpadding="1" cellspacing="1"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;div style="margin: 0px;"&gt;
SubTreeCost&lt;/div&gt;
&lt;/td&gt;&lt;td&gt;&lt;div style="margin: 0px;"&gt;
CompileTime(ms)&lt;/div&gt;
&lt;/td&gt;&lt;td&gt;&lt;div style="margin: 0px;"&gt;
LastElapsedTime(sec)&amp;nbsp;&lt;/div&gt;
&lt;/td&gt;&lt;td&gt;&lt;div style="margin: 0px;"&gt;
LastCPUTime(sec)&amp;nbsp;&lt;/div&gt;
&lt;/td&gt;&lt;td&gt;&lt;div style="margin: 0px;"&gt;
LastLogicalReads&lt;/div&gt;
&lt;/td&gt;&lt;td&gt;&lt;div style="margin: 0px;"&gt;
LastRows&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div style="margin: 0px;"&gt;
1st&lt;/div&gt;
&lt;/td&gt;&lt;td&gt;&lt;div style="margin: 0px;"&gt;
5.0630900&lt;/div&gt;
&lt;/td&gt;&lt;td&gt;&lt;div style="margin: 0px;"&gt;
17&lt;/div&gt;
&lt;/td&gt;&lt;td&gt;&lt;div style="margin: 0px;"&gt;
1.345748000&lt;/div&gt;
&lt;/td&gt;&lt;td&gt;&lt;div style="margin: 0px;"&gt;
0.541942000&lt;/div&gt;
&lt;/td&gt;&lt;td&gt;&lt;div style="margin: 0px;"&gt;
2,249&lt;/div&gt;
&lt;/td&gt;&lt;td&gt;&lt;div style="margin: 0px;"&gt;
118,744&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div style="margin: 0px;"&gt;
2nd&lt;/div&gt;
&lt;/td&gt;&lt;td&gt;&lt;div style="margin: 0px;"&gt;
&lt;span style="color: red;"&gt;5.0630900&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;&lt;td&gt;&lt;span style="color: red;"&gt;17&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="color: red;"&gt;0.181764000&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="color: red;"&gt;0.066875000&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="color: red;"&gt;1564&lt;/span&gt;&lt;/td&gt;&lt;td&gt;12&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;3rd&lt;/td&gt;&lt;td&gt;&lt;span style="color: blue;"&gt;0.5626740&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="color: blue;"&gt;6&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="color: blue;"&gt;0.123931000&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="color: blue;"&gt;0.010333000&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="color: blue;"&gt;398&lt;/span&gt;&lt;/td&gt;&lt;td&gt;12&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;-- 1st: Parameter Sniffing with OR issue&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;-- Clustered Index Scan, return 118,744 rows&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;StatementSubTreeCost 5.0630900&lt;/li&gt;
&lt;li&gt;CompileTime(ms) 17&lt;/li&gt;
&lt;li&gt;CompileCPU(ms) 17&lt;/li&gt;
&lt;li&gt;CompileMemory(KB) 1216&lt;/li&gt;
&lt;li&gt;LastElapsedTime(sec) 1.345748000&lt;/li&gt;
&lt;li&gt;LastCPUTime(sec) 0.541942000&lt;/li&gt;
&lt;li&gt;LastLogicalReads 2,249&lt;/li&gt;
&lt;li&gt;LastRows 118,744&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;b&gt;-- 2nd: Bad: Clustered Index&amp;nbsp;&lt;span style="color: red;"&gt;Scan&lt;/span&gt;, return 12 rows&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;-- Reuse bad execution plan&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;StatementSubTreeCost 5.0630900&lt;/li&gt;
&lt;li&gt;CompileTime(ms) 17&lt;/li&gt;
&lt;li&gt;CompileCPU(ms) 17&lt;/li&gt;
&lt;li&gt;CompileMemory(KB) 1216&lt;/li&gt;
&lt;li&gt;LastElapsedTime(sec) 0.181764000&lt;/li&gt;
&lt;li&gt;LastCPUTime(sec) 0.066875000&lt;/li&gt;
&lt;li&gt;LastLogicalReads 1564&lt;/li&gt;
&lt;li&gt;LastRows 12&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;b&gt;-- 3rd: "sp_recompile"&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;-- Good: Index Scan + Clustered Index&amp;nbsp;&lt;span style="color: blue;"&gt;Seek&lt;/span&gt;, return 12 rows&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;StatementSubTreeCost 0.5626740&lt;/li&gt;
&lt;li&gt;CompileTime(ms) 6&lt;/li&gt;
&lt;li&gt;CompileCPU(ms) 6&lt;/li&gt;
&lt;li&gt;CompileMemory(KB) 1000&lt;/li&gt;
&lt;li&gt;LastElapsedTime(sec) 0.123931000&lt;/li&gt;
&lt;li&gt;LastCPUTime(sec) 0.010333000&lt;/li&gt;
&lt;li&gt;LastLogicalReads 398&lt;/li&gt;
&lt;li&gt;LastRows 12&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;比較&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;編譯 Compile 時間的最大值： 0.017 sec。&lt;/li&gt;
&lt;li&gt;每次執行時間的差距(0.181764 - 0.12393)&amp;nbsp;：&amp;nbsp;&lt;span style="color: blue;"&gt;0.057834 sec&lt;/span&gt;。&lt;/li&gt;
&lt;li&gt;每次 Logical Read 的差距(1564 - 398)：1166。&lt;/li&gt;
&lt;li&gt;加入 編譯 Compile 時間的耗損(0.057834 - 0.017)：&lt;span style="color: blue;"&gt;0.040834 sec&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
若執行 100 次，Reuse bad execution plan 與 Recompile stored procedure 來比較：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;執行時間差距 ( (0.181764)*100 - (0.12393 + 0.017)*100 ) ，多耗用： 4.0834 sec。&lt;/li&gt;
&lt;li&gt;Logical Read 差距(1166 *100) ，多耗用：116,600。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
由上，隨著執行次數越頻繁，因故重複使用 效能差的 Execution Plan，卻是耗費更多的資源。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
可以得知：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;非 每秒 都要大量執行 或 同時間會大量執行 的程式，改用重新編譯 Stored Procedure，獲取更佳的執行效能。這筆支出，是值得的。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: sql"&gt;-- Get execution plan for cached query: [CompileTime(ms)], [StatementSubTreeCost], [LastElapsedTime(sec)], LastLogicalReads, LastRows etc.
WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' as ns)

SELECT TOP 10 st.text [TSQL], DB_NAME(st.dbid) [DB], 
 TRY_CAST(qp.query_plan.value('(/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/@StatementSubTreeCost)[1]', 'float') 
 AS decimal(38,7)) [StatementSubTreeCost],
 qp.query_plan.value('(/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/ns:QueryPlan/@CompileTime)[1]', 'int') [CompileTime(ms)], 
 qp.query_plan.value('(/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/ns:QueryPlan/@CompileCPU)[1]', 'int') [CompileCPU(ms)],
 qp.query_plan.value('(/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/ns:QueryPlan/@CompileMemory)[1]', 'int') [CompileMemory(KB)],
 qs.last_elapsed_time/1000000.0 [LastElapsedTime(sec)],
 qs.last_worker_time/1000000.0 [LastCPUTime(sec)],
 qs.last_logical_reads LastLogicalReads,
 qs.last_physical_reads LastPhysicalRead,
 qs.last_logical_writes LastlogicalWrites,
 qs.last_rows LastRows,
 cp.usecounts [ExecutionCount], cp.size_in_bytes/1024.0 [PlanSize(KB)],
 cp.cacheobjtype [CacheObject], cp.objtype [ObjType], qs.plan_generation_num [PlanRecompile],
 qp.query_plan.query('(/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/ns:QueryPlan/ns:ParameterList/ns:ColumnReference[@Column])') [ParameterList],
 qp.query_plan [QueryPlan], cp.plan_handle, qs.last_execution_time, qs.creation_time
FROM sys.dm_exec_cached_plans cp INNER JOIN sys.dm_exec_query_stats qs
         ON cp.plan_handle = qs.plan_handle
 CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) st
 CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) qp
WHERE st.dbid = DB_ID('AdventureWorks2014') 
-- AND cp.objtype = 'Proc' CHARINDEX ('Products', st.text) &amp;gt;0
-- st.text LIKE '%xxx%'
ORDER BY StatementSubTreeCost DESC;
GO
&lt;/pre&gt;
&lt;br /&gt;
-- figure&amp;nbsp;23_Get execution plan for cached query&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7a3pNK2W6f81Yd3zg6GZc1DomEpr_ux1ysISGlHaPZTe7QGN0qHnMEEipsfJTvAnYwtQDoT5UukDcXhz3R9y-TDaZGdEfQ3rDo7Dto3XZ_2rDvVvj18bAV9qhTA_lkm0taxDAkTpYb-Q/s1600/23_Get+execution+plan+for+cached+query.png" imageanchor="1"&gt;&lt;img border="0" height="280" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7a3pNK2W6f81Yd3zg6GZc1DomEpr_ux1ysISGlHaPZTe7QGN0qHnMEEipsfJTvAnYwtQDoT5UukDcXhz3R9y-TDaZGdEfQ3rDo7Dto3XZ_2rDvVvj18bAV9qhTA_lkm0taxDAkTpYb-Q/s640/23_Get+execution+plan+for+cached+query.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Sample Code&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
20180825_Get_parse_compile_execute_time_SQL&lt;br /&gt;
&lt;a href="https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing"&gt;https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Reference&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[Case Study] Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (1)&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or.html"&gt;http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
[SQL Server] Get SubTreeCost, CompileTime, CompileMemory, Execution Count, Plan Recompile from Plan Cache - 子樹成本&lt;br /&gt;
&lt;div style="-webkit-text-stroke-width: 0px; color: black; font-family: &amp;quot;Times New Roman&amp;quot;; font-size: medium; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; margin: 0px; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"&gt;
&lt;a href="http://sharedderrick.blogspot.com/2017/12/sql-server-get-subtreecost-compiletime.html"&gt;http://sharedderrick.blogspot.com/2017/12/sql-server-get-subtreecost-compiletime.html&lt;/a&gt;&lt;/div&gt;
</description><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzgK3G1vLXrH_hneMFvzos6RDyx86KZYSyCMWHHuprdWo_GCjd3x1rZ4wKAMU79Y4ry3XlTkIHT8Y4KtBJ2jcNAtpKgmzpkKhszdlJpi0s6Mw_i_6Pw9BsL7qK-7Rzym4XkjD_Fq2kS_c/s72-c/12_Compare_ComileTime_CPU.png" width="72"/><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><title>Get parse, compile, and execute time for SQL statement. 取得 剖析、編譯 和 執行 SQL 查詢 所耗用的時間</title><link>http://sharedderrick.blogspot.com/2018/08/get-parse-compile-and-execute-time-for.html</link><category>Performance Tuning</category><category>SQL Server</category><author>noreply@blogger.com (DerrickLaLa)</author><pubDate>Sun, 26 Aug 2018 16:26:00 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1420955872914622499.post-2642715962165904319</guid><description>&lt;br /&gt;
&lt;br /&gt;
若取得 剖析、編譯 和 執行 SQL 查詢 所耗用的時間，可以使用以下方式：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;使用 SET STATISTICS IO, TIME ON 取得。&lt;/li&gt;
&lt;li&gt;檢視 Execution Plan 取得。&lt;/li&gt;
&lt;li&gt;使用 DMV 直接上 記憶體 Cache 區取得。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghZvoDk8iwAC-LaC7up3Mivj8idyyBtLboIgRmy8BdPt6qm9NnvMtaVNtInq_4fweZsd6Q84gvj6mjFV1KumYJ1fL4hEAV5eNi4pMyAtp1EcQ8yZWUVcodJrADg0ij3POzH4QXzH_0dyk/s1600/04_Actual_Execution_Plan_Complie_Time_CPU.png" imageanchor="1"&gt;&lt;img border="0" height="444" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghZvoDk8iwAC-LaC7up3Mivj8idyyBtLboIgRmy8BdPt6qm9NnvMtaVNtInq_4fweZsd6Q84gvj6mjFV1KumYJ1fL4hEAV5eNi4pMyAtp1EcQ8yZWUVcodJrADg0ij3POzH4QXzH_0dyk/s640/04_Actual_Execution_Plan_Complie_Time_CPU.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Get parse, compile, and execute time for SQL statement.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;取得 剖析、編譯 和 執行 SQL 查詢 所耗用的時間&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
01. 依序執行以下 SQL 陳述式：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;SET STATISTICS IO, TIME ON: 是用於取得 剖析、編譯和執行的 時間與 Disk IO 資訊。&amp;nbsp;&lt;/li&gt;
&lt;li&gt;sp_recompile: 是用於要求 SQL Server 重新編譯 Stored Procedure。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
以下是各個的功用說明。&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;SET STATISTICS IO, TIME ON:&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;TIME:&amp;nbsp;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;顯示剖析、編譯和執行每個陳述式所需要的毫秒數。&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Displays the number of milliseconds required to parse, compile, and execute each statement.&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;IO:&amp;nbsp;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;顯示 Transact-SQL 陳述式所產生之磁碟活動量的相關資訊。&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Causes SQL Server to display information regarding the amount of disk activity generated by Transact-SQL statements.&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;sp_recompile:&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;在下次執行預存程序、觸發程序以及使用者定義函數時，重新編譯它們。&amp;nbsp;&lt;/li&gt;
&lt;li&gt;其運作方式是從程序快取中卸除現有的計畫，以便強制在下次執行程序或觸發程序時建立新的計畫。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;01_SET STATISTICS IO TIME ON&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAMltXfqp-VtyFP9dN0FZxJwZTIz8BjUpTpYmzGAKWJfML4gPB9wvlGQcJ69S43E0nCKpm5zX_SEQBBPBmx9EHDiE6qpIfEfOwlL_eezaglftCWQmiVx6mD6JJaO7fyog67Xbq0jgHbMo/s1600/01_SET+STATISTICS+IO+TIME+ON.png" imageanchor="1"&gt;&lt;img border="0" height="246" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAMltXfqp-VtyFP9dN0FZxJwZTIz8BjUpTpYmzGAKWJfML4gPB9wvlGQcJ69S43E0nCKpm5zX_SEQBBPBmx9EHDiE6qpIfEfOwlL_eezaglftCWQmiVx6mD6JJaO7fyog67Xbq0jgHbMo/s640/01_SET+STATISTICS+IO+TIME+ON.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 執行 Stored Procedure。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;EXEC dbo.GetSalesList 43659&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;02_Execute_Stored_Procedure&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGCwrdQ4rrwoFWFpDmef1ry8PAJa6kSjj7IrqQkFMRoMk3C4vzpymnxvn1Gwmj22L2t4FZAtp-M1aQTA6rc0TzbqoglqRVUhM_BEnRv1Hq4ggNGOSnaiMmemFDSNY7CxsnmhaQ0hyMwkc/s1600/02_Execute_Stored_Procedure.png" imageanchor="1"&gt;&lt;img border="0" height="152" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGCwrdQ4rrwoFWFpDmef1ry8PAJa6kSjj7IrqQkFMRoMk3C4vzpymnxvn1Gwmj22L2t4FZAtp-M1aQTA6rc0TzbqoglqRVUhM_BEnRv1Hq4ggNGOSnaiMmemFDSNY7CxsnmhaQ0hyMwkc/s640/02_Execute_Stored_Procedure.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 檢視輸出，可以看到 parse and compile time:&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;SQL Server Execution Times:&lt;br /&gt;
&amp;nbsp; &amp;nbsp;CPU time = 0 ms,&amp;nbsp; elapsed time = 0 ms.&lt;br /&gt;
SQL Server parse and compile time:&lt;br /&gt;
&amp;nbsp; &amp;nbsp;CPU time = 0 ms, elapsed time = 0 ms.&lt;br /&gt;
&lt;b&gt;SQL Server parse and compile time:&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp;CPU time = 15 ms, elapsed time = 43 ms.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;03_parse and compile time&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTn7YR08olvz78E7fpIxQ4b0h1LtYYmGQNbELHuyB-ov6EKWwQ5MlLWlz_4SDNktkx1thbFzndk__Q3iqdr5vXlxJo3N99DJmIRiBjh_Y-bOeOijW11mnHUxTXXlKxWzUf0Wb0bR1knWQ/s1600/03_parse+and+compile+time.png" imageanchor="1"&gt;&lt;img border="0" height="430" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTn7YR08olvz78E7fpIxQ4b0h1LtYYmGQNbELHuyB-ov6EKWwQ5MlLWlz_4SDNktkx1thbFzndk__Q3iqdr5vXlxJo3N99DJmIRiBjh_Y-bOeOijW11mnHUxTXXlKxWzUf0Wb0bR1knWQ/s640/03_parse+and+compile+time.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
04. 也可以由 Execution Plan 取得相關的資訊:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;CompileCPU: 12&lt;/li&gt;
&lt;li&gt;CompileMemory: 1008&lt;/li&gt;
&lt;li&gt;CompileTime: 35&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;04_Actual_Execution_Plan_Complie_Time_CPU&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKncHkPqjpovTC0KTfaQXiimhY5AGkUCr3Mf3rzLrqhVHETHB0UxNaTmjcGE8irOve49GVaHgg53jAlyTXBAxUw5JHTSEqxEXvIGaSssSI9fllpylQrKiqUdJmK-_bphkrZn4Wq9EREw4/s1600/04_Actual_Execution_Plan_Complie_Time_CPU.png" imageanchor="1"&gt;&lt;img border="0" height="444" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKncHkPqjpovTC0KTfaQXiimhY5AGkUCr3Mf3rzLrqhVHETHB0UxNaTmjcGE8irOve49GVaHgg53jAlyTXBAxUw5JHTSEqxEXvIGaSssSI9fllpylQrKiqUdJmK-_bphkrZn4Wq9EREw4/s640/04_Actual_Execution_Plan_Complie_Time_CPU.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
05. 想要知道 &lt;span style="color: blue;"&gt;已經執行&lt;/span&gt;過 SQL Statement 的 編譯相關資源嗎？&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue;"&gt;使用 DMV 直接上 記憶體 Cache 區，自行取用 :)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;CompileTime(ms): 35&lt;/li&gt;
&lt;li&gt;CompileCPU(ms): 12&lt;/li&gt;
&lt;li&gt;CompileMemory(KB): 1008&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;05_Get execution plan for cached query&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1LtZoKG7BDzG6JOqmRFC03FwOYljMWFxyO2eb5xevFwrwfkLivcqRcdr9XLtDzcmFRUYVsi-ITeeiNJpzqnpPNwIMm5UKvogdkfgJGR9OxJUpDm0g7HL_qR9PwB8E5sjfedc5TRCSFco/s1600/05_Get+execution+plan+for+cached+query.png" imageanchor="1"&gt;&lt;img border="0" height="376" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1LtZoKG7BDzG6JOqmRFC03FwOYljMWFxyO2eb5xevFwrwfkLivcqRcdr9XLtDzcmFRUYVsi-ITeeiNJpzqnpPNwIMm5UKvogdkfgJGR9OxJUpDm0g7HL_qR9PwB8E5sjfedc5TRCSFco/s640/05_Get+execution+plan+for+cached+query.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: sql"&gt;-- Get execution plan for cached query: Execution Count, Plan Recompile, ParameterList, Query Plan, CompileTime, CompileMemory, SubTreeCost, etc.
WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' as ns)

SELECT TOP 10 st.text [TSQL], DB_NAME(st.dbid) [DB], 
 TRY_CAST(qp.query_plan.value('(/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/@StatementSubTreeCost)[1]', 'float') 
 AS decimal(38,7)) [StatementSubTreeCost],
 qp.query_plan.value('(/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/ns:QueryPlan/@CompileTime)[1]', 'int') [CompileTime(ms)], 
 qp.query_plan.value('(/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/ns:QueryPlan/@CompileCPU)[1]', 'int') [CompileCPU(ms)],
 qp.query_plan.value('(/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/ns:QueryPlan/@CompileMemory)[1]', 'int') [CompileMemory(KB)],
 qp.query_plan.value('(/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/@RetrievedFromCache)[1]', 'nvarchar(50)') [RetrievedFromCache],
 cp.usecounts [ExecutionCount], cp.size_in_bytes/1024.0 [PlanSize(KB)],
 cp.cacheobjtype [CacheObject], cp.objtype [ObjType], qs.plan_generation_num [PlanRecompile],
 qp.query_plan.query('(/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/ns:QueryPlan/ns:ParameterList/ns:ColumnReference[@Column])') [ParameterList],
 qp.query_plan [QueryPlan], cp.plan_handle, qs.last_execution_time, qs.creation_time
FROM sys.dm_exec_cached_plans cp INNER JOIN sys.dm_exec_query_stats qs
         ON cp.plan_handle = qs.plan_handle
 CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) st
 CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) qp
WHERE st.dbid = DB_ID('AdventureWorks2014') 
-- AND cp.objtype = 'Proc' CHARINDEX ('Products', st.text) &amp;gt;0
-- st.text LIKE '%xxx%'
ORDER BY StatementSubTreeCost DESC;
GO
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Sample Code&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
20180825_Get_parse_compile_execute_time_SQL&lt;br /&gt;
&lt;a href="https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing"&gt;https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Reference&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[Case Study] Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (1)&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or.html"&gt;http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
[SQL Server] Get SubTreeCost, CompileTime, CompileMemory, Execution Count, Plan Recompile from Plan Cache - 子樹成本&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2017/12/sql-server-get-subtreecost-compiletime.html"&gt;http://sharedderrick.blogspot.com/2017/12/sql-server-get-subtreecost-compiletime.html&lt;/a&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</description><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghZvoDk8iwAC-LaC7up3Mivj8idyyBtLboIgRmy8BdPt6qm9NnvMtaVNtInq_4fweZsd6Q84gvj6mjFV1KumYJ1fL4hEAV5eNi4pMyAtp1EcQ8yZWUVcodJrADg0ij3POzH4QXzH_0dyk/s72-c/04_Actual_Execution_Plan_Complie_Time_CPU.png" width="72"/><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><title>[Case Study] Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (3)</title><link>http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or_24.html</link><category>Performance Tuning</category><category>SQL Server</category><author>noreply@blogger.com (DerrickLaLa)</author><pubDate>Fri, 24 Aug 2018 06:57:00 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1420955872914622499.post-709875523978307708</guid><description>&lt;br /&gt;
延續前一篇文章：&lt;a href="http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or_23.html"&gt;[Case Study] Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (2)&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
繼續討論 Parameter Sniffing 的 因應之道：&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;使用 EXEC ... WITH RECOMPILE&lt;/li&gt;
&lt;li&gt;使用 sp_recompile&lt;/li&gt;
&lt;li&gt;修改 Stored Procedure，使用 Local Variables&lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;修改 Stored Procedure，使用 WITH RECOMPILE&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;修改 Stored Procedure，使用 OPTION RECOMPILE&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;改寫&amp;nbsp;Stored Procedure，使用 UNION ALL&lt;/li&gt;
&lt;li&gt;改寫&amp;nbsp;Stored Procedure，使用 IF ELSE&lt;/li&gt;
&lt;li&gt;改寫&amp;nbsp;Stored Procedure，使用 Dynamic SQL: EXEC&lt;/li&gt;
&lt;li&gt;改寫&amp;nbsp;Stored Procedure，使用 Dynamic SQL: sp_executesql&lt;/li&gt;
&lt;li&gt;因應需求，分別建立 Stored Procedure&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Parameter Sniffing with OR Operator issue,&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;當 Parameter Sniffing 遇上 OR 運算子(3)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;4. 修改 Stored Procedure，使用 WITH RECOMPILE&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
說明&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
WITH RECOMPILE&lt;br /&gt;
&lt;ul&gt;&lt;ul&gt;
&lt;/ul&gt;
&lt;li&gt;停用 Reuse Execution Plan 功能&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;每次執行&amp;nbsp;Stored Procedure，都要 Recompile SQL 陳述式 ，並執行 Parameter Sniffing，這勢必多耗用系統資源。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
注意事項&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;修改 Stored Procedure 程式碼，牽扯版本問題。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;需要與 SQL Developer 人員溝通討論。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;停用 Reuse Execution Plan 功能&lt;/li&gt;
&lt;li&gt;每次執行&amp;nbsp;Stored Procedure，都要 Recompile SQL 陳述式，這勢必多耗用系統資源。&lt;/li&gt;
&lt;li&gt;以 Execute Frequency(執行頻率) 來考量&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="color: red;"&gt;不適用於 every second(每秒) 都要執行 或 同時間會大量執行 等情境。&lt;/span&gt;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="color: red;"&gt;每次都重新編譯，將過度耗用系統資源。&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;適用於: 年報、季報、月報、周報、日報、小時報或數分鐘報等&lt;/span&gt;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;如能因重新編譯 Stored Procedure，獲取更佳的執行效能。這筆支出，值得。&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
01.&amp;nbsp;建立使用&amp;nbsp;&lt;span style="color: blue;"&gt;WITH RECOMPILE&lt;/span&gt;&amp;nbsp;的 Stored Procedure。&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;必須修改原來的程式碼。&lt;/li&gt;
&lt;li&gt;在 Stored Procedure 內，額外再宣告 &lt;span style="color: blue;"&gt;WITH RECOMPILE&amp;nbsp;&lt;/span&gt;來使用。&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
-- figure&amp;nbsp;41_ALTER Proc WITH RECOMPILE&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsAa_7YqrrQ4zv8CgcXdbidudvbzCEtBPgpkmulENVGeSZ8lqsc455FRwG6oy4ug4MiAYveYKNkjtETFPChgypmkymP0DkoHmLc61CheJ_FOzuiivmezadxKUqvbER3kg5fzwemXCRLdQ/s1600/41_ALTER+Proc+WITH+RECOMPILE.png" imageanchor="1"&gt;&lt;img border="0" height="328" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsAa_7YqrrQ4zv8CgcXdbidudvbzCEtBPgpkmulENVGeSZ8lqsc455FRwG6oy4ug4MiAYveYKNkjtETFPChgypmkymP0DkoHmLc61CheJ_FOzuiivmezadxKUqvbER3kg5fzwemXCRLdQ/s640/41_ALTER+Proc+WITH+RECOMPILE.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02.&amp;nbsp;執行 使用 WITH RECOMPILE 的 Stored Procedure。&lt;br /&gt;
&lt;br /&gt;
分別輸入 NULL 與 43659。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;當輸入 NULL:&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;取回全部資料，回傳 118,744 rows，使用 Clustered Index Scan。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;當輸入 43659:&amp;nbsp;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;取回指定 SalesOrderID 的資料，回傳 &lt;span style="color: blue;"&gt;12&lt;/span&gt; rows。&lt;/li&gt;
&lt;li&gt;經 Query Optimizer 執行優化後，使用 &lt;span style="color: blue;"&gt;Index &lt;/span&gt;&lt;span style="color: red;"&gt;Scan &lt;/span&gt;&lt;span style="color: blue;"&gt;+ Clustered Index Seek&lt;/span&gt;。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;沒有使用到效率差的 Clustered Index Scan。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;這是&lt;span style="color: blue;"&gt;有提升執行效能的 Execution Plan&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
若非 每秒 都要執行 或 同時間會大量執行 的程式，能因 WITH RECOMPILE 重新編譯 Stored Procedure，獲取更佳的執行效能。這筆支出，是值得的。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;42_EXEC_Proc WITH RECOMPILE&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQesjsbBeFz61iwIzL9I9O6d5nXhTPbPc9jr2h9l8FkSwa9s3ErTuJdYosf938kxSxaOi4D4TD4Aw0lRA3Ewytac8hwiQIojBk5MTQsl2tgtW4HHcEp9PTzF1n_1NWt0de9vUWI_o_SiI/s1600/42_EXEC_Proc+WITH+RECOMPILE.png" imageanchor="1"&gt;&lt;img border="0" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQesjsbBeFz61iwIzL9I9O6d5nXhTPbPc9jr2h9l8FkSwa9s3ErTuJdYosf938kxSxaOi4D4TD4Aw0lRA3Ewytac8hwiQIojBk5MTQsl2tgtW4HHcEp9PTzF1n_1NWt0de9vUWI_o_SiI/s640/42_EXEC_Proc+WITH+RECOMPILE.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 觀察 Execution Plan:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;EXEC GetSalesList_WITH_RECOMPILE NULL&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;使用 Clustered Index Scan。&lt;/li&gt;
&lt;li&gt;Actual Rows: 118,744。&lt;/li&gt;
&lt;li&gt;Est Rows: 116,322，這是 Estimated Number of Rows。&lt;/li&gt;
&lt;li&gt;Reads: &lt;span style="color: red;"&gt;2,315&lt;/span&gt;，這是 Logical Reads。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;EXEC GetSalesList_WITH_RECOMPILE 43659&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;重新編譯 ，獲取執行效能更佳的 Execution Plan。&lt;/li&gt;
&lt;li&gt;使用 Index Scan + Clustered Index Seek。&lt;/li&gt;
&lt;li&gt;Actual Rows: &lt;span style="color: blue;"&gt;12&lt;/span&gt;。&lt;/li&gt;
&lt;li&gt;Est Rows: &lt;span style="color: blue;"&gt;12&lt;/span&gt;，這是 Estimated Number of Rows。&lt;/li&gt;
&lt;li&gt;Reads: &lt;span style="color: blue;"&gt;464&lt;/span&gt;，這是 Logical Reads。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;43_Plan_Explorer&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEA1mfUqoEiVNx4NJvw_aCcTbTEUR3zAsvzKnsdKRCKVzknc3LMIA9GTZCe19z-Xue0Ljs3SRh2ycGaGUosPsm9Eh0sQWTvUHnMBcxMo700gLmpLzwl0CnfSf50zGSGGJGuFHs8AxlnaM/s1600/43_Plan_Explorer.png" imageanchor="1"&gt;&lt;img border="0" height="280" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEA1mfUqoEiVNx4NJvw_aCcTbTEUR3zAsvzKnsdKRCKVzknc3LMIA9GTZCe19z-Xue0Ljs3SRh2ycGaGUosPsm9Eh0sQWTvUHnMBcxMo700gLmpLzwl0CnfSf50zGSGGJGuFHs8AxlnaM/s640/43_Plan_Explorer.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
04.&amp;nbsp;進一步觀察 Execution Plan&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Operation caused residual IO.&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;The actual number of rows read was &lt;span style="color: red;"&gt;121,317&lt;/span&gt;, but the number of rows returned was &lt;span style="color: blue;"&gt;12&lt;/span&gt;.&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
雖然已經不用 Clustered Index Scan，Query Optimizer 判斷改用 Index Scan，但實際僅取回 12 rows，卻仍須讀取 121,317 rows，仍是耗用過多的系統資源。&lt;br /&gt;
&lt;br /&gt;
讓我們繼續設計出更有效率的執行方式與 Execution Plan!&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;44_Plan_Explorer&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEif6SMgYdlnclkGEr7Sq4oG1iP1UHLzwcMUhZ6t_0Sd0eCrLDxgw3J2TtOD638KbSl6EIlbyKRWcRa6WDSMBThyphenhyphenVXnsTraV83t4zFqbQVVnvdRMeYmt50xWI-iMaqbH5inZ6jrtqyrcDfg/s1600/44_Plan_Explorer.png" imageanchor="1"&gt;&lt;img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEif6SMgYdlnclkGEr7Sq4oG1iP1UHLzwcMUhZ6t_0Sd0eCrLDxgw3J2TtOD638KbSl6EIlbyKRWcRa6WDSMBThyphenhyphenVXnsTraV83t4zFqbQVVnvdRMeYmt50xWI-iMaqbH5inZ6jrtqyrcDfg/s640/44_Plan_Explorer.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;5. 修改 Stored Procedure，使用 OPTION RECOMPILE&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
說明&lt;br /&gt;
&lt;br /&gt;
使用 OPTION (RECOMPILE)&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;針對特定的 SQL Statement，停用其&amp;nbsp;Reuse Execution Plan 功能。&lt;/li&gt;
&lt;li&gt;僅 Recompile 指定的 SQL Statement，&lt;span style="color: blue;"&gt;並且可使用到 Local Variable 的內容值&lt;/span&gt;。&lt;/li&gt;
&lt;li&gt;每次執行 Stored Procedure，僅需 Recompile 指定的 SQL 陳述式，但仍有耗用過多資源的顧慮。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
注意事項&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;修改 Stored Procedure 程式碼，牽扯版本問題。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;需要與 SQL Developer 人員溝通討論。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;每次執行 Stored Procedure，僅需 Recompile 指定的 SQL 陳述式，仍有耗用過多資源的顧慮。&lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;以 Execute Frequency(執行頻率) 來考量&lt;/span&gt;&lt;/li&gt;
&lt;ul&gt;&lt;ul&gt;
&lt;li&gt;不適用於 every second(每秒) 都要執行 或 同時間會大量執行 等情境。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;每次都重新編譯，將過度耗用系統資源。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;適用於: 年報、季報、月報、周報、日報、小時報或數分鐘報等&lt;/span&gt;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;如能因重新編譯 Stored Procedure，獲取更佳的執行效能。這筆支出，值得。&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;li&gt;而且，OPTION (RECOMPILE) 可以解除 "Local Variables / OPTIMIZE FOR UNKNOWN" 所帶來的副作用，但 sp_recompile&amp;nbsp; 與 WITH RECOMPILE 是無此功效。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
01.&amp;nbsp;建立使用 OPTION RECOMPILE 的 Stored Procedure。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;必須修改原來的程式碼。&lt;/li&gt;
&lt;li&gt;在指定的 SQL Statement，額外再宣告 OPTION RECOMPILE&amp;nbsp;來使用。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;51_ALTER Proc OPTION RECOMPILE&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIkB8JB3FOX8bZrGeu6-kgF0mHnQ43k22RHHCNyXtZ-mSNHM9eV8PZFKRcL88iHLiCrBqlZtv1x0zwyLC1XZAwT-s5h0m5hjVypsxEiTneuPb-jq_pdWL16z841_NCkEmYYet2Hhzq22E/s1600/51_ALTER+Proc+OPTION+RECOMPILE.png" imageanchor="1"&gt;&lt;img border="0" height="328" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIkB8JB3FOX8bZrGeu6-kgF0mHnQ43k22RHHCNyXtZ-mSNHM9eV8PZFKRcL88iHLiCrBqlZtv1x0zwyLC1XZAwT-s5h0m5hjVypsxEiTneuPb-jq_pdWL16z841_NCkEmYYet2Hhzq22E/s640/51_ALTER+Proc+OPTION+RECOMPILE.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02.&amp;nbsp;執行 使用 OPTION RECOMPILE&amp;nbsp;的 Stored Procedure。&lt;br /&gt;
&lt;br /&gt;
分別輸入 NULL 與 43659。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;當輸入 NULL:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;取回全部資料，回傳 118,744 rows，使用 Clustered Index Scan。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;當輸入 43659:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;取回指定 SalesOrderID 的資料，回傳 12 rows。&lt;/li&gt;
&lt;li&gt;經 Query Optimizer 執行優化後，使用 Index &lt;span style="color: blue;"&gt;seek &lt;/span&gt;+ Clustered Index &lt;span style="color: blue;"&gt;Seek&lt;/span&gt;。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;沒有使用到效率差的 Clustered Index Scan、Index Scan。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;這是有提升執行效能的 Execution Plan。&lt;/li&gt;
&lt;li&gt;與 WITH RECOMPILE 比較起來，OPTION RECOMPILE&amp;nbsp;有機會產更有效率的 Execution Plan。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
若非 每秒 都要大量執行 或 同時間會大量執行 的程式，能因 OPTION RECOMPILE&amp;nbsp;重新編譯 Stored Procedure，獲取更佳的執行效能。這筆支出，是值得的。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;52_EXEC_Proc OPTION RECOMPILE&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFtZD68tJt1vBS7t_eOMaxEiopbkZtjj36gsQlvcrPVKgzBn3wbxXw07hcK0Ds8y-zDwMygbVPGiDMGvirONxk1BJTXIPz8ncQUerXEtenX9FXAJp1kNS5ALmw8FjAxdjWYqNQk1vD124/s1600/52_EXEC_Proc+OPTION+RECOMPILE.png" imageanchor="1"&gt;&lt;img border="0" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFtZD68tJt1vBS7t_eOMaxEiopbkZtjj36gsQlvcrPVKgzBn3wbxXw07hcK0Ds8y-zDwMygbVPGiDMGvirONxk1BJTXIPz8ncQUerXEtenX9FXAJp1kNS5ALmw8FjAxdjWYqNQk1vD124/s640/52_EXEC_Proc+OPTION+RECOMPILE.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 觀察 Execution Plan:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;EXEC GetSalesList_OPTION_RECOMPILE NULL&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;使用 Clustered Index Scan。&lt;/li&gt;
&lt;li&gt;Actual Rows: 118,744。&lt;/li&gt;
&lt;li&gt;Est Rows: 116,322，這是 Estimated Number of Rows。&lt;/li&gt;
&lt;li&gt;Reads: 2,313，這是 Logical Reads。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;EXEC GetSalesList_OPTION_RECOMPILE 43659&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;僅 Recompile 指定的 SQL Statement，就可以獲得執行效能更佳的 Execution Plan。&lt;/li&gt;
&lt;li&gt;使用 &lt;span style="color: blue;"&gt;Index Seek + Clustered Index Seek&lt;/span&gt;。&lt;/li&gt;
&lt;li&gt;Actual Rows: 12。&lt;/li&gt;
&lt;li&gt;Est Rows: 12，這是 Estimated Number of Rows。&lt;/li&gt;
&lt;li&gt;Reads: &lt;span style="color: blue;"&gt;76&lt;/span&gt;，這是 Logical Reads。&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
-- figure&amp;nbsp;53_Plan_Explorer&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYZf5_kn76E8faHAbbgP3qe7-AYiIKlkMHLkwi431gPn43Ab6fWvLpnP7v6QacYkLk1JAS3MwzGHkwxRzzDA9EZdCH2CFzyujfbKxBisR_m8lNjyJPWC4Vz8HJ69IbZCVyMcnSG5GXzyk/s1600/53_Plan_Explorer.png" imageanchor="1"&gt;&lt;img border="0" height="372" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYZf5_kn76E8faHAbbgP3qe7-AYiIKlkMHLkwi431gPn43Ab6fWvLpnP7v6QacYkLk1JAS3MwzGHkwxRzzDA9EZdCH2CFzyujfbKxBisR_m8lNjyJPWC4Vz8HJ69IbZCVyMcnSG5GXzyk/s640/53_Plan_Explorer.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Sample Code&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
20180821_Parameter_Sniffing_with_OR_Operator&lt;br /&gt;
&lt;a href="https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing"&gt;https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Reference&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
[Case Study] Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (1)&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or.html"&gt;http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Parameter Sniffing: Dynamic SQL, sp_executesql and EXEC (Parameter Sniffing 與 動態 SQL)&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/parameter-sniffing-dynamic-sql.html"&gt;http://sharedderrick.blogspot.com/2018/08/parameter-sniffing-dynamic-sql.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
[Case Study] Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (2)&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or_23.html"&gt;http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or_23.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Compare "WITH RECOMPILE / sp_recompile" with "OPTION RECOMPILE"&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/02/sql-server-compare-with-recompile-with.html"&gt;http://sharedderrick.blogspot.com/2018/02/sql-server-compare-with-recompile-with.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Parameter Sniffing: Local Variable&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/01/sql-server-parameter-sniffing-local.html"&gt;http://sharedderrick.blogspot.com/2018/01/sql-server-parameter-sniffing-local.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Parameter Sniffing: OPTION OPTIMIZE FOR UNKNOWN&lt;br /&gt;
http://sharedderrick.blogspot.com/2018/01/sql-server-parameter-sniffing-option_7.html&lt;br /&gt;
&lt;br /&gt;
Parameter Sniffing: OPTION OPTIMIZE FOR UNKNOWN 2&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/01/sql-server-parameter-sniffing-option_14.html"&gt;http://sharedderrick.blogspot.com/2018/01/sql-server-parameter-sniffing-option_14.html&lt;/a&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</description><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsAa_7YqrrQ4zv8CgcXdbidudvbzCEtBPgpkmulENVGeSZ8lqsc455FRwG6oy4ug4MiAYveYKNkjtETFPChgypmkymP0DkoHmLc61CheJ_FOzuiivmezadxKUqvbER3kg5fzwemXCRLdQ/s72-c/41_ALTER+Proc+WITH+RECOMPILE.png" width="72"/><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><title>[Case Study] Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (2)</title><link>http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or_23.html</link><category>Performance Tuning</category><category>SQL Server</category><author>noreply@blogger.com (DerrickLaLa)</author><pubDate>Thu, 23 Aug 2018 07:27:00 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1420955872914622499.post-4801299246718622918</guid><description>&lt;br /&gt;
&lt;br /&gt;
延續前一篇文章：&lt;a href="http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or.html"&gt;[Case Study] Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (1)&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
繼續討論&amp;nbsp;Parameter Sniffing 的 因應之道：&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;使用 EXEC ... WITH RECOMPILE&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;使用 sp_recompile&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;修改 Stored Procedure，使用 Local Variables&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;修改 Stored Procedure，使用 WITH RECOMPILE&lt;/li&gt;
&lt;li&gt;修改 Stored Procedure，使用 OPTION RECOMPILE&lt;/li&gt;
&lt;li&gt;改寫&amp;nbsp;Stored Procedure，使用 UNION ALL&lt;/li&gt;
&lt;li&gt;改寫&amp;nbsp;Stored Procedure，使用 IF ELSE&lt;/li&gt;
&lt;li&gt;改寫&amp;nbsp;Stored Procedure，使用 Dynamic SQL: EXEC&lt;/li&gt;
&lt;li&gt;改寫 Stored Procedure，使用 Dynamic SQL: sp_executesql&lt;/li&gt;
&lt;li&gt;因應需求，分別建立 Stored Procedure&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Parameter Sniffing with OR Operator issue,&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;當 Parameter Sniffing 遇上 OR 運算子(2)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;1. 使用 EXEC ... WITH RECOMPILE&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
說明：&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;無須修改 Stored Procedure 程式碼&lt;/li&gt;
&lt;li&gt;執行 stored procedure，搭配 WITH RECOMPILE&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;不方便。還需要 帶入 User Parameter。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;執行當下 Recompile (&lt;span style="background-color: white; font-family: &amp;quot;segoe ui&amp;quot; , &amp;quot;segoeui&amp;quot; , &amp;quot;segoe wp&amp;quot; , &amp;quot;helvetica neue&amp;quot; , &amp;quot;helvetica&amp;quot; , &amp;quot;tahoma&amp;quot; , &amp;quot;arial&amp;quot; , sans-serif; font-size: 16px;"&gt;重新編譯&lt;/span&gt;) 此 stored procedure。&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
注意事項：&lt;br /&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;單次性的處理。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;處理此次 因 Parameter Sniffing 機制，導致重複使用到 效能不佳 的 Execution Plan。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;但仍繼續使用 Parameter Sniffing 機制。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;若 Input Parameter 仍差異性過大，仍會遭遇重複使用到 效能不佳 的&amp;nbsp;Execution Plan 。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
01.&amp;nbsp;執行當下 Recompile (重新編譯) 此 stored procedure。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;11_EXEC_WITH RECOMPILE&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLn_dPZQc7417SN0hFY8_SN35lRQG2J7nWxkiWQyGJ-mA8NcRs47rO2KNBHs2yN1CswJ0o6mn-ezhp9OKunGjIlSlJNmT74Y7ugsSE8LjuOncq_L4szHtIjKO8wdI8FrdUT6g051hGBhc/s1600/11_EXEC_WITH+RECOMPILE.png" imageanchor="1"&gt;&lt;img border="0" height="198" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLn_dPZQc7417SN0hFY8_SN35lRQG2J7nWxkiWQyGJ-mA8NcRs47rO2KNBHs2yN1CswJ0o6mn-ezhp9OKunGjIlSlJNmT74Y7ugsSE8LjuOncq_L4szHtIjKO8wdI8FrdUT6g051hGBhc/s640/11_EXEC_WITH+RECOMPILE.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 觀察 Execution Plan&lt;br /&gt;
&lt;br /&gt;
-- Good: Index Scan + Clustered Index Seek, return 12 rows&lt;br /&gt;
EXEC dbo.GetSalesList 43659 WITH RECOMPILE&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;改用 Index Scan + Clustered Index Seek，Good Execution Plan。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;12_Good_Index Scan_Clustered Index Seek&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbPXiK2vOSUajvN-k3c-vJPlU_JACK_9gc-xBb_zDVX5ztpnxS03bGHWsdNSjCyNs5NpDzthYFzMaMAWH217xal-xfeAFrg6MocAYdClWNyayxtqFzCs_mqZ3Guo80OZqP9Drmcf4cjy8/s1600/12_Good_Index+Scan_Clustered+Index+Seek.png" imageanchor="1"&gt;&lt;img border="0" height="146" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbPXiK2vOSUajvN-k3c-vJPlU_JACK_9gc-xBb_zDVX5ztpnxS03bGHWsdNSjCyNs5NpDzthYFzMaMAWH217xal-xfeAFrg6MocAYdClWNyayxtqFzCs_mqZ3Guo80OZqP9Drmcf4cjy8/s640/12_Good_Index+Scan_Clustered+Index+Seek.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 使用 Plan Explorer 來觀察&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
EXEC dbo.GetSalesList 43659 WITH RECOMPILE&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;改用 Index Scan + Clustered Index Seek，Good Execution Plan。&lt;/li&gt;
&lt;li&gt;Actual Rows: &lt;span style="color: blue;"&gt;12&lt;/span&gt;。&lt;/li&gt;
&lt;li&gt;Est Rows: &lt;span style="color: blue;"&gt;12&lt;/span&gt;，這是 Estimated Number of Rows。&lt;/li&gt;
&lt;li&gt;Reads: &lt;span style="color: blue;"&gt;464&lt;/span&gt;，這是 Logical Reads。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
與 "dbo.GetSalesList NULL" 對比起來，節省了大量的系統資源，Est Cost 是整體的 10%。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;13_Plan_Explorer&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXsAVUwLi5M8nYEHpOGcmEMb-7aF-x6iQChA7L2CSF_h6s6WirCu2Zd_s89nA1bDrH_cUuVASpUM3m_Ly4ZcmY_P51SJyEG8M9kLeGasKkIUeCcNiqXKi-vtZkUkhmqQMycbrwdNVe4wE/s1600/13_Plan_Explorer.png" imageanchor="1"&gt;&lt;img border="0" height="284" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXsAVUwLi5M8nYEHpOGcmEMb-7aF-x6iQChA7L2CSF_h6s6WirCu2Zd_s89nA1bDrH_cUuVASpUM3m_Ly4ZcmY_P51SJyEG8M9kLeGasKkIUeCcNiqXKi-vtZkUkhmqQMycbrwdNVe4wE/s640/13_Plan_Explorer.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;2. 使用 sp_recompile&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
說明：&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;無須修改 Stored Procedure 程式碼。&lt;/li&gt;
&lt;li&gt;等到下次執行 stored procedure，才將 Recompile(重新編譯) 此 stored procedure。&lt;/li&gt;
&lt;li&gt;使用到此 Table 的各項 SQL 物件：stored procedure, trigger, or user-defined function，都將 Recompile 。&lt;/li&gt;
&lt;li&gt;比較起來，不先移除 該 stored procedure 的 Execution Plan。&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
注意事項：&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;單次性的處理。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;處理此次 因 Parameter Sniffing 機制，導致重複使用到 效能不佳 的 Execution Plan。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;但仍繼續使用 Parameter Sniffing 機制。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;若 Input Parameter 仍差異性過大，仍會遭遇重複使用到 效能不佳 的 Execution Plan 。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;ul&gt;&lt;ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
01. 使用 sp_recompile 對 Table 後，再執行 Stored Procedure。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;21_sp_recompile&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvP_zKm0fXjR8izxa3AwX7OHEUiiOxiM0L_0fFbmSe9A3XsyV73SFbq1jkn1Iw7RvqZ2xfksRSjV3-b8jjJ5dc1rZtfCYKyD-B9hDRBdMMaMuO4yumXsX9epidLFbiGmptUHQnksyfrEM/s1600/21_sp_recompile.png" imageanchor="1"&gt;&lt;img border="0" height="280" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvP_zKm0fXjR8izxa3AwX7OHEUiiOxiM0L_0fFbmSe9A3XsyV73SFbq1jkn1Iw7RvqZ2xfksRSjV3-b8jjJ5dc1rZtfCYKyD-B9hDRBdMMaMuO4yumXsX9epidLFbiGmptUHQnksyfrEM/s640/21_sp_recompile.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02.&amp;nbsp;使用 Plan Explorer 來觀察&lt;br /&gt;
&lt;br /&gt;
-- Good: Index Scan + Clustered Index Seek, return 12 rows&lt;br /&gt;
EXEC sp_recompile 'dbo.GetSalesList'&lt;br /&gt;
GO&lt;br /&gt;
EXEC dbo.GetSalesList 43659&lt;br /&gt;
GO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;改用 Index Scan + Clustered Index Seek，Good Execution Plan。&lt;/li&gt;
&lt;li&gt;Actual Rows: &lt;span style="color: blue;"&gt;12&lt;/span&gt;。&lt;/li&gt;
&lt;li&gt;Est Rows: &lt;span style="color: blue;"&gt;12&lt;/span&gt;，這是 Estimated Number of Rows。&lt;/li&gt;
&lt;li&gt;Reads: &lt;span style="color: blue;"&gt;464&lt;/span&gt;，這是 Logical Reads。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
與 "dbo.GetSalesList NULL" 對比起來，節省了大量的系統資源，Est Cost 是整體的 10%。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;22_Plan_Explorer&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZfpJJOJMxhE6sFIvzuNxg3_jMfZhqujzFQYn0YMLzfXZD0OhyssjUqjVnOEXyUMIhh21lasYqOWAjD6CZsNSATD-md8G4jBrFojFIxv1yn16vzVKxz8EKbcT8CWBhK611TOfTCJ3kXio/s1600/22_Plan_Explorer.png" imageanchor="1"&gt;&lt;img border="0" height="296" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZfpJJOJMxhE6sFIvzuNxg3_jMfZhqujzFQYn0YMLzfXZD0OhyssjUqjVnOEXyUMIhh21lasYqOWAjD6CZsNSATD-md8G4jBrFojFIxv1yn16vzVKxz8EKbcT8CWBhK611TOfTCJ3kXio/s640/22_Plan_Explorer.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;3. 修改 Stored Procedure，使用 "Local Variables / OPTIMIZE FOR UNKNOWN"&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
說明：&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;修改 Stored Procedure 程式碼，牽扯版本問題。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;需要與 SQL Developer 人員溝通討論。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;設定 Query Optimizer 僅使用 Average Distribution (平均分配) 機制來執行 cardinality estimation。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;至於輸入什麼 parameter 值，回傳多少筆數等等，設定讓 Query Optimizer 都不要列入考量。&lt;/li&gt;
&lt;li&gt;停用 Parameter Sniffing。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;評估方式，例如：&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;使用 equality (等號)，則 Query Optimizer 僅使用 density vector 來執行 cardinality estimation，也就是： &lt;span style="color: blue;"&gt;Rows * All density&lt;/span&gt;。&lt;/li&gt;
&lt;li&gt;使用 Inequality (不相等)，則 Query Optimizer 連 density vector 也不用了，就直接設定資料列總數的 30% 來執行 cardinality estimation，也就是： &lt;span style="color: blue;"&gt;Rows * 30%&lt;/span&gt; 。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
注意事項：&lt;/div&gt;
&lt;ul&gt;&lt;ul&gt;
&lt;li&gt;停用 Parameter Sniffing 機制。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;僅重複使用&amp;nbsp;"Local Variables / OPTIMIZE FOR UNKNOWN" 機制產生的 Execution Plan。&lt;/li&gt;
&lt;li&gt;&lt;span style="color: red;"&gt;堪用，非效能最佳化&lt;/span&gt;的 Execution Plan。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;看似節省編譯 Execution Plan 的系統資源，卻陷入 執行效能不佳的窘境，甚至耗損更多的 系統資源!&lt;/li&gt;
&lt;li&gt;必須修改 SQL 程式碼。&lt;/li&gt;
&lt;li&gt;不適用於需求是 高效能 的系統。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
01. 建立使用 Local Variable 的 Stored Procedure。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;必須修改原來的程式碼。&lt;/li&gt;
&lt;li&gt;在 Stored Procedure 內，&lt;span style="color: red;"&gt;額外再宣告&lt;/span&gt; Local Variable 來使用。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure 31_ALTER Proc Local Variables_issue&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFtPurWQNN5gGd0VT3IQVlV362aoB1R1tegeFhsgBqsmkQwjkF2csdiAUBgGKAk90mUbaUdK58shMTrrHDxJPK3pc2-QZ_J8xjV2cAD2PB-wIK8Ug1udpaUzQ6X3G5i2xPM2guf-Ur8pU/s1600/31_ALTER_Proc_Local+Variables_issue.png" imageanchor="1"&gt;&lt;img border="0" height="362" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFtPurWQNN5gGd0VT3IQVlV362aoB1R1tegeFhsgBqsmkQwjkF2csdiAUBgGKAk90mUbaUdK58shMTrrHDxJPK3pc2-QZ_J8xjV2cAD2PB-wIK8Ug1udpaUzQ6X3G5i2xPM2guf-Ur8pU/s640/31_ALTER_Proc_Local+Variables_issue.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 執行 使用 Local Variable 的 Stored Procedure。&lt;br /&gt;
&lt;br /&gt;
分別輸入 NULL 與 43659。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;當輸入 NULL:&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;取回全部資料，回傳 118,744 rows，使用 Clustered Index Scan。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;當輸入 43659:&amp;nbsp;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;取回指定 SalesOrderID 的資料，回傳 &lt;span style="color: blue;"&gt;12&lt;/span&gt; rows，但卻使用 &lt;span style="color: red;"&gt;Clustered Index Scan&lt;/span&gt;。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;應該使用 &lt;span style="color: blue;"&gt;Index Seek&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;啟用 "Local Variables / OPTIMIZE FOR UNKNOWN" 判斷機制，停用 Parameter Sniffing 機制。&lt;/li&gt;
&lt;li&gt;看似節省了編譯 Execution Plan 的 CPU 資源，卻陷入 執行效能不佳的窘境，導致耗用更多的系統資源！&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;32_EXEC_Local Variables_issue&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBOaiOO1C1FMyVMiFLELQlmruCLJlA8P7p7X7w71nFfr6BbXeR3W5SMEM5u5oQOYa7zcMn_mZban9pbcCRwvJ66BPSnphkFZVDhAmh1fXs4d6Ioja0B6OvEEaC1wUELbq_Q0CjfV5Y1mk/s1600/31_Local+Variables_issue.png" imageanchor="1"&gt;&lt;img border="0" height="228" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBOaiOO1C1FMyVMiFLELQlmruCLJlA8P7p7X7w71nFfr6BbXeR3W5SMEM5u5oQOYa7zcMn_mZban9pbcCRwvJ66BPSnphkFZVDhAmh1fXs4d6Ioja0B6OvEEaC1wUELbq_Q0CjfV5Y1mk/s640/31_Local+Variables_issue.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 觀察: 這 2 份 Execution Plan。&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;因啟用 "Local Variables / OPTIMIZE FOR UNKNOWN" 判斷機制&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;停用 Parameter Sniffing 機制。&lt;/li&gt;
&lt;li&gt;兩份完全相同的 Execution Plan。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;都是使用&amp;nbsp;&amp;nbsp;&lt;span style="color: red;"&gt;Clustered Index Scan&lt;/span&gt;！&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Clustered Index Scan, return 118,744 rows&lt;br /&gt;
EXEC GetSalesList_Local_Variable NULL&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;使用 Clustered Index Scan。&lt;/li&gt;
&lt;li&gt;Actual Rows: 118,744。&lt;/li&gt;
&lt;li&gt;Est Rows: &lt;span style="color: red;"&gt;38,387&lt;/span&gt;，這是 Estimated Number of Rows，不精確。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;因啟用 "Local Variables / OPTIMIZE FOR UNKNOWN" 機制所計算出來的回傳筆數，與事實不符。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;Reads: 2,249，這是 Logical Reads。&lt;/li&gt;
&lt;li&gt;Est Cost 卻都顯示 50%，這是 Estimated Subtree Cost，不精確，不具備參考價值。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Bad: Clustered Index Scan, return &lt;span style="color: blue;"&gt;12 &lt;/span&gt;rows&lt;br /&gt;
EXEC GetSalesList_Local_Variable 43659&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;卻使用 &lt;span style="color: red;"&gt;Clustered Index Scan&lt;/span&gt;。&lt;/li&gt;
&lt;li&gt;Actual Rows: &lt;span style="color: blue;"&gt;12&lt;/span&gt;。&lt;/li&gt;
&lt;li&gt;Est Rows: &lt;span style="color: red;"&gt;38,387&lt;/span&gt;，這是 Estimated Number of Rows，與 Actual Rows 差異極大，不精確。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;因啟用 "Local Variables / OPTIMIZE FOR UNKNOWN" 機制所計算出來的回傳筆數，與事實不符。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;Reads: &lt;span style="color: red;"&gt;1,562&lt;/span&gt;，這是 Logical Reads。&lt;/li&gt;
&lt;li&gt;Est Cost 卻都顯示 50%，這是 Estimated Subtree Cost，不精確，不具備參考價值。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;33_Plan_Explorer&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_TGkNDxrmfH67pSwqpkegU0vE853RISdyr5sKQKddXXavxCg1v_T2Sok2QuDZ5OKyb4P9fX1P5HQ8ibTWJc1RT7n55iL-Wd7Ms-KSBHdbMTQqEGtE6J7BIT0UdP_LgJ6Pb4PgwwNHVyA/s1600/32_Plan_Explorer.png" imageanchor="1"&gt;&lt;img border="0" height="432" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_TGkNDxrmfH67pSwqpkegU0vE853RISdyr5sKQKddXXavxCg1v_T2Sok2QuDZ5OKyb4P9fX1P5HQ8ibTWJc1RT7n55iL-Wd7Ms-KSBHdbMTQqEGtE6J7BIT0UdP_LgJ6Pb4PgwwNHVyA/s640/32_Plan_Explorer.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
進一步觀察 Execution Plan&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Operation caused residual IO.&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;The actual number of rows read was &lt;span style="color: red;"&gt;121,317&lt;/span&gt;, but the number of rows returned was &lt;span style="color: blue;"&gt;12&lt;/span&gt;.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
實際僅取回 &lt;span style="color: blue;"&gt;12&lt;/span&gt; rows，卻因啟用 "Local Variables / OPTIMIZE FOR UNKNOWN" 機制，額外讀取 &lt;span style="color: red;"&gt;121,317&lt;/span&gt; rows，浪費了大量的 IO 系統資源!&lt;br /&gt;
&lt;br /&gt;
看似節省編譯 Execution Plan 的系統資源，卻陷入 執行效能不佳的窘境，甚至耗損更多的 系統資源!&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;34_Plan_Explorer&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgueptiVc17rjcx7SkHaT3pHDRl7e6StYyGIWyZePyXyTbFOZtLaqfzRL6euIW7K4d6LjS5pS9Xkv0_0yxzAlV5axPKDZ-26L2dDLanwM9tsGwD8sXKAtMt52iwNMBngGEXlwGXvHfiTUE/s1600/33_Plan_Explorer.png" imageanchor="1"&gt;&lt;img border="0" height="322" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgueptiVc17rjcx7SkHaT3pHDRl7e6StYyGIWyZePyXyTbFOZtLaqfzRL6euIW7K4d6LjS5pS9Xkv0_0yxzAlV5axPKDZ-26L2dDLanwM9tsGwD8sXKAtMt52iwNMBngGEXlwGXvHfiTUE/s640/33_Plan_Explorer.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
身為 SQL Developer 人員&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;需要去 了解 資料特性、回傳筆數、執行頻率、Index、Statistics&amp;nbsp;等，選擇適合的因應之道，方能開發出 高效能 的 Stored Procedure。&lt;/li&gt;
&lt;li&gt;一昧使用 "Local Variables / OPTIMIZE FOR UNKNOWN" 機制，或許，節省了開發時程，但卻落得 Stored Procedure 執行效能不佳的窘境!&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Sample Code&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
20180821_Parameter_Sniffing_with_OR_Operator&lt;br /&gt;
&lt;a href="https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing"&gt;https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Reference&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
[Case Study] Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (1)&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or.html"&gt;http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Parameter Sniffing: Dynamic SQL, sp_executesql and EXEC (Parameter Sniffing 與 動態 SQL)&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/parameter-sniffing-dynamic-sql.html"&gt;http://sharedderrick.blogspot.com/2018/08/parameter-sniffing-dynamic-sql.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Compare "WITH RECOMPILE / sp_recompile" with "OPTION RECOMPILE"&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/02/sql-server-compare-with-recompile-with.html"&gt;http://sharedderrick.blogspot.com/2018/02/sql-server-compare-with-recompile-with.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Parameter Sniffing: Local Variable&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/01/sql-server-parameter-sniffing-local.html"&gt;http://sharedderrick.blogspot.com/2018/01/sql-server-parameter-sniffing-local.html&lt;/a&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
Parameter Sniffing: OPTION OPTIMIZE FOR UNKNOWN&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/01/sql-server-parameter-sniffing-option_7.html"&gt;http://sharedderrick.blogspot.com/2018/01/sql-server-parameter-sniffing-option_7.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Parameter Sniffing: OPTION OPTIMIZE FOR UNKNOWN 2&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/01/sql-server-parameter-sniffing-option_14.html"&gt;http://sharedderrick.blogspot.com/2018/01/sql-server-parameter-sniffing-option_14.html&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
</description><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLn_dPZQc7417SN0hFY8_SN35lRQG2J7nWxkiWQyGJ-mA8NcRs47rO2KNBHs2yN1CswJ0o6mn-ezhp9OKunGjIlSlJNmT74Y7ugsSE8LjuOncq_L4szHtIjKO8wdI8FrdUT6g051hGBhc/s72-c/11_EXEC_WITH+RECOMPILE.png" width="72"/><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><title>[Case Study] Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (1)</title><link>http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or.html</link><category>Performance Tuning</category><category>SQL Server</category><author>noreply@blogger.com (DerrickLaLa)</author><pubDate>Wed, 22 Aug 2018 06:59:00 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1420955872914622499.post-5435384450618416091</guid><description>&lt;br /&gt;
在先前的文章裡，陸續介紹過 Parameter Sniffing 的基本概念。本文以 Case Study (案例分享) 方式來綜合討論。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue;"&gt;Parameter Sniffing&lt;/span&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;優點：藉由重複使用 Execution Plan 的機制，來節省編譯 Execution Plan 資源 的耗損。&lt;/li&gt;
&lt;li&gt;缺點：卻存在著誤用 Execution Plan，導致效能更糟的問題。&lt;/li&gt;
&lt;li&gt;看似節省編譯 Execution Plan 的 CPU 資源，卻掉入效能不佳的窘境。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue;"&gt;OR 運算子&lt;/span&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;可篩選多值，延展條件式的功能，十分彈性，但卻潛藏效能不佳的問題。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
當兩者結合，遭遇到效能不佳的困境時，該如何解決呢?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
本文彙整 10 種 Parameter Sniffing 的 因應之道：&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;使用 &lt;span style="color: blue;"&gt;EXEC ... WITH RECOMPILE&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;使用 &lt;span style="color: blue;"&gt;sp_recompile&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;修改 Stored Procedure，使用 &lt;span style="color: blue;"&gt;"Local Variables / OPTIMIZE FOR UNKNOWN"&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;修改 Stored Procedure，使用 &lt;span style="color: blue;"&gt;WITH RECOMPILE&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;修改 Stored Procedure，使用 &lt;span style="color: blue;"&gt;OPTION RECOMPILE&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;改寫 Stored Procedure，使用 &lt;span style="color: blue;"&gt;UNION ALL&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;改寫 Stored Procedure，使用 &lt;span style="color: blue;"&gt;IF ELSE&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;改寫 Stored Procedure，使用 &lt;span style="color: blue;"&gt;Dynamic SQL: EXEC&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;改寫 Stored Procedure，使用 &lt;span style="color: blue;"&gt;Dynamic SQL: sp_executesql&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;因應需求，分別建立 &lt;span style="color: blue;"&gt;individual Stored Procedure&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
想知道之間的區別、應用時機 與 優缺點嗎？&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
本系列文章&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or.html"&gt;Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (1)&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or_23.html"&gt;Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (2)&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or_24.html"&gt;Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (3)&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/case-study-parameter-sniffing-with-or_31.html"&gt;Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (4)&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/09/case-study-parameter-sniffing-with-or.html"&gt;Parameter Sniffing with OR Operator issue, 當 Parameter Sniffing 遇上 OR 運算子 (5)&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Parameter Sniffing with OR Operator issue,&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;當 Parameter Sniffing 遇上 OR 運算子(1)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
01. 建立 Stored Procedure:&amp;nbsp;dbo.GetSalesList&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
條件式:&amp;nbsp; WHERE (@SalesOrderID IS NULL &lt;span style="color: blue;"&gt;OR &lt;/span&gt;sd.SalesOrderID = @SalesOrderID)&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;@SalesOrderID IS NULL: 當 @SalesOrderID 是 NULL 時，取回全部的資料，回傳 118,744 rows。&lt;/li&gt;
&lt;li&gt;sd.SalesOrderID = @SalesOrderID: 取回 指定的 SalesOrderID 的 資料，回傳&amp;nbsp;&lt;span style="color: blue;"&gt;12&amp;nbsp;&lt;/span&gt;rows。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
以 Index 使用策略來看：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;這兩個條件式，應該是使用不同的 Index 存取方式，例如：Index &lt;span style="color: red;"&gt;Scan&lt;/span&gt;、Index &lt;span style="color: blue;"&gt;Seek &lt;/span&gt;等。&lt;/li&gt;
&lt;li&gt;但透過 OR 運算子，整合在同一個 Stored Procedure，會遇到什麼效能上的難題呢？&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;01_Parameter Sniffing with OR issue&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlMtEEZMNsI-P0A7AkamVt-rI5UPLXCUTIDZTavR-vN1PnbsM9eYmc_rdjP2RKtNNDV4IGqo40rjPPsZerao_IDRSP9HvLyknkRM2KuTJK0_Phpcu8tzBXvfzTS9LJtmuSNBiqsqIPQgg/s1600/01_Parameter+Sniffing+with+OR+issue.png" imageanchor="1"&gt;&lt;img border="0" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlMtEEZMNsI-P0A7AkamVt-rI5UPLXCUTIDZTavR-vN1PnbsM9eYmc_rdjP2RKtNNDV4IGqo40rjPPsZerao_IDRSP9HvLyknkRM2KuTJK0_Phpcu8tzBXvfzTS9LJtmuSNBiqsqIPQgg/s640/01_Parameter+Sniffing+with+OR+issue.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 執行此 Stored Procedure:&amp;nbsp;dbo.GetSalesList。&lt;br /&gt;
&lt;br /&gt;
分別輸入 NULL 與&amp;nbsp;43659。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;當輸入 NULL:&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;取回全部資料，回傳 118,744 rows，使用&amp;nbsp;Clustered Index Scan。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;當輸入 43659:&amp;nbsp;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;取回指定 SalesOrderID 的資料，回傳 &lt;span style="color: blue;"&gt;12 &lt;/span&gt;rows，但卻仍是使用 &lt;span style="color: red;"&gt;Clustered Index Scan&lt;/span&gt;。&lt;/li&gt;
&lt;li&gt;由於 Parameter Sniffing 發揮功效，重複使用 Execution Plan。&lt;/li&gt;
&lt;li&gt;雖然節省了編譯 Execution Plan 的 CPU 資源，但卻因故誤用效能不佳的 Bad Execution Plan，導致耗用更多的系統資源！&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;02_EXEC_Parameter Sniffing with OR issue&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiL2uW6VQ-TxppAe1ZBEu297FuNkQaDh72Pn4goFiF4m0VlyastQF155WVLGycKs9itSUxrVJrrHgdHhyNZphvWW6rO14N0FfGs0Z2Mjl2qVT4ZWIxH-ApnYqL2IRyH2oT0OUml5I4jPLE/s1600/02_EXEC_Parameter+Sniffing+with+OR+issue.png" imageanchor="1"&gt;&lt;img border="0" height="244" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiL2uW6VQ-TxppAe1ZBEu297FuNkQaDh72Pn4goFiF4m0VlyastQF155WVLGycKs9itSUxrVJrrHgdHhyNZphvWW6rO14N0FfGs0Z2Mjl2qVT4ZWIxH-ApnYqL2IRyH2oT0OUml5I4jPLE/s640/02_EXEC_Parameter+Sniffing+with+OR+issue.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 觀察: 這 2 隻 Stored Procedure 的 Execution Plan。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;由於 Parameter Sniffing 發揮功效，重複使用 Execution Plan。&lt;/li&gt;
&lt;li&gt;都是使用 &lt;span style="color: red;"&gt;Clustered Index Scan&lt;/span&gt;！&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;03_Clustered Index Scan&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCyaHc3WSeZ7aq2M-lG7cAFPbN7sP2E6MJWn118FOGAWsHAutNEY84g9C6p3Tqx4VvPu1ZAT0Gs6Zqy4W_NJX1N3FeCy-iyLkcimaLJo0-H7CFvD5BcvP8-CQSqF6GHii1RottDW72A4A/s1600/03_Clustered+Index+Scan.png" imageanchor="1"&gt;&lt;img border="0" height="284" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCyaHc3WSeZ7aq2M-lG7cAFPbN7sP2E6MJWn118FOGAWsHAutNEY84g9C6p3Tqx4VvPu1ZAT0Gs6Zqy4W_NJX1N3FeCy-iyLkcimaLJo0-H7CFvD5BcvP8-CQSqF6GHii1RottDW72A4A/s640/03_Clustered+Index+Scan.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
04. 綜合觀察&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
EXEC dbo.GetSalesList NULL&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;使用&amp;nbsp;Clustered Index Scan。&lt;/li&gt;
&lt;li&gt;Actual Rows: 118,744。&lt;/li&gt;
&lt;li&gt;Est Rows: 116,322，這是 Estimated Number of Rows。&lt;/li&gt;
&lt;li&gt;Reads: 2,335，這是&amp;nbsp;Logical Reads。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
EXEC dbo.GetSalesList 43659&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;仍是使用 &lt;span style="color: red;"&gt;Clustered Index Scan&lt;/span&gt;。&lt;/li&gt;
&lt;li&gt;Actual Rows: &lt;span style="color: blue;"&gt;12&lt;/span&gt;。&lt;/li&gt;
&lt;li&gt;Est Rows: &lt;span style="color: red;"&gt;116,322&lt;/span&gt;，這是 Estimated Number of Rows。&lt;/li&gt;
&lt;li&gt;Reads: &lt;span style="color: red;"&gt;1,564&lt;/span&gt;，這是&amp;nbsp;Logical Reads。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
這就是錯誤的重複使用 Execution Plan 後，所導致的效能低落問題。&lt;br /&gt;
看似節省編譯 Execution Plan 的 CPU 資源，卻掉入效能不佳的窘境。&lt;br /&gt;
&lt;br /&gt;
下圖的 Execution Plan 是屬於 EXEC dbo.GetSalesList NULL。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;04_Plan_Explorer&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiF-5ALQmmrw-liMIgRxxB5SqymOPFvy1TQ4Eq74gKQ5UnM3esz0cpq-5ZuyX33HfpA2jhgakfPpdvP2Jnqbq3EiNnndBPbZd-FAHYSt8AqjQaPjinpBoMb42I5d6JHsRUZEy-ytGolVt0/s1600/04_Plan_Explorer.png" imageanchor="1"&gt;&lt;img border="0" height="432" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiF-5ALQmmrw-liMIgRxxB5SqymOPFvy1TQ4Eq74gKQ5UnM3esz0cpq-5ZuyX33HfpA2jhgakfPpdvP2Jnqbq3EiNnndBPbZd-FAHYSt8AqjQaPjinpBoMb42I5d6JHsRUZEy-ytGolVt0/s640/04_Plan_Explorer.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
05. 下圖的 Execution Plan 是屬於 EXEC dbo.GetSalesList 43659。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;05_Plan_Explorer&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJLwI-Zt8uLPu5_8zNwbJyhFtZFp0ZI0l3v_f8VC8JzaWew_n5N2LCx9JFxxz-hf1xXJFWa7dfzpeY_laaDst25Z4tEP7-v93KO5BOaaxu67O9RPOzP8-LZDmZpFRppDzPAQ9qy2cpjD4/s1600/05_Plan_Explorer.png" imageanchor="1"&gt;&lt;img border="0" height="434" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJLwI-Zt8uLPu5_8zNwbJyhFtZFp0ZI0l3v_f8VC8JzaWew_n5N2LCx9JFxxz-hf1xXJFWa7dfzpeY_laaDst25Z4tEP7-v93KO5BOaaxu67O9RPOzP8-LZDmZpFRppDzPAQ9qy2cpjD4/s640/05_Plan_Explorer.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Sample Code&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
20180821_Parameter_Sniffing_with_OR_Operator&lt;br /&gt;
&lt;a href="https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing"&gt;https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Reference&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Parameter Sniffing: Dynamic SQL, sp_executesql and EXEC (Parameter Sniffing 與 動態 SQL)&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/08/parameter-sniffing-dynamic-sql.html"&gt;http://sharedderrick.blogspot.com/2018/08/parameter-sniffing-dynamic-sql.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Compare "WITH RECOMPILE / sp_recompile" with "OPTION RECOMPILE"&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/02/sql-server-compare-with-recompile-with.html"&gt;http://sharedderrick.blogspot.com/2018/02/sql-server-compare-with-recompile-with.html&lt;/a&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</description><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlMtEEZMNsI-P0A7AkamVt-rI5UPLXCUTIDZTavR-vN1PnbsM9eYmc_rdjP2RKtNNDV4IGqo40rjPPsZerao_IDRSP9HvLyknkRM2KuTJK0_Phpcu8tzBXvfzTS9LJtmuSNBiqsqIPQgg/s72-c/01_Parameter+Sniffing+with+OR+issue.png" width="72"/><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><title>[SQL Server] Disabled Index still update Statistics, 停用索引 仍會更新 統計值</title><link>http://sharedderrick.blogspot.com/2018/08/sql-server-disabled-index-still-update.html</link><category>Index</category><category>SQL Server</category><author>noreply@blogger.com (DerrickLaLa)</author><pubDate>Sat, 18 Aug 2018 14:52:00 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1420955872914622499.post-3076522667941493164</guid><description>&lt;br /&gt;
在維護大型系統上，需要定期評估 Index 適用性。&lt;br /&gt;
若判斷無須使用該 Index，則執行 Disabled Index 與進一步觀察對系統的影響程度。&lt;br /&gt;
&lt;br /&gt;
提醒&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;若經確認無需使用該 Index 後，應移除該 Index。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
Disabled Index 會防止使用者存取 Index，Query Optimizer 不使用此 Index。但 SQL Server 仍會維護與更新該 Index 的統計值。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Disabled Index 仍會更新&amp;nbsp;Statistics&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnBEhheqq5UODPQMvqCoNYbaSymKXKTmQyOIVYqUda75_uHxDE1HAhQqfm6Ut7RWINERm6wLnLStJtKfWpzxb0ShDJ5RYhyphenhyphenoQ26lsRN0fNAPxX56VQUv4qzzt_PYQUuJOZWlWl4H3JxQk/s1600/22_Get+all+indexes+and+Statistics+last+updated+datetime.png" imageanchor="1"&gt;&lt;img border="0" height="170" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnBEhheqq5UODPQMvqCoNYbaSymKXKTmQyOIVYqUda75_uHxDE1HAhQqfm6Ut7RWINERm6wLnLStJtKfWpzxb0ShDJ5RYhyphenhyphenoQ26lsRN0fNAPxX56VQUv4qzzt_PYQUuJOZWlWl4H3JxQk/s640/22_Get+all+indexes+and+Statistics+last+updated+datetime.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Disabled Index still update Statistics, 停用索引 仍會更新 統計值&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
01. 使用 sp_helpindex 觀察資料表&amp;nbsp;[Person].[Address] 的 Index 資訊&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;01_Index&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5GoObRhxg9VPIrIEYGt_1_AXR4TeZWN27nBPubPnF5K4FS6tiuER9RdpkA4r5Nmj8QvYo0mQK5jDL_2PAwQrP3N4eaEuHDVF3TZZqyDsgpVXvaGUXicCsp2H8_CPY_1Zq12dVPzN5mxM/s1600/01_Index.png" imageanchor="1"&gt;&lt;img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5GoObRhxg9VPIrIEYGt_1_AXR4TeZWN27nBPubPnF5K4FS6tiuER9RdpkA4r5Nmj8QvYo0mQK5jDL_2PAwQrP3N4eaEuHDVF3TZZqyDsgpVXvaGUXicCsp2H8_CPY_1Zq12dVPzN5mxM/s640/01_Index.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 使用 DMV 與&amp;nbsp;STATS_DATE 觀察 全部資料表的 Index 與 Statistics 資訊&lt;br /&gt;
&lt;br /&gt;
Get all indexes and Statistics last updated datetime&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;02_Get all indexes and Statistics last updated datetime&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEht9pYf0uPaAHOv5uKqvbolJIqm0HhQlZhCSCz_Izlr0vrQw3BXCx_kUZKUV6esyNF_FzbthjDxUp2OYs42q86toAb1WdIgrD5EmRrqAQaWv-81dAzr8ZnpIGuXNj9qhNxPNyYJuOBljvY/s1600/02_Get+all+indexes+and+Statistics+last+updated+datetime.png" imageanchor="1"&gt;&lt;img border="0" height="270" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEht9pYf0uPaAHOv5uKqvbolJIqm0HhQlZhCSCz_Izlr0vrQw3BXCx_kUZKUV6esyNF_FzbthjDxUp2OYs42q86toAb1WdIgrD5EmRrqAQaWv-81dAzr8ZnpIGuXNj9qhNxPNyYJuOBljvY/s640/02_Get+all+indexes+and+Statistics+last+updated+datetime.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 停用 Index&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Disable Nonclustered Index&lt;/li&gt;
&lt;li&gt;IX_Address_StateProvinceID&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;11_Disable Nonclustered Index&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKXFyMwrPM1n6jVAZ2pHM2jYEOdpz1AHxMsu1jIPD9ar3kDspy3FFwjicAHtj5-YYIJWpWWYBMmtncEKe2Lmm94TwwrP3Z5zVS48fUTl7VhUydRpyKRFBmrcMRHtmFoM62mnvDzstzw98/s1600/11_Disable+Nonclustered+Index.png" imageanchor="1"&gt;&lt;img border="0" height="210" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKXFyMwrPM1n6jVAZ2pHM2jYEOdpz1AHxMsu1jIPD9ar3kDspy3FFwjicAHtj5-YYIJWpWWYBMmtncEKe2Lmm94TwwrP3Z5zVS48fUTl7VhUydRpyKRFBmrcMRHtmFoM62mnvDzstzw98/s640/11_Disable+Nonclustered+Index.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
04. 觀察 資料表的 Index 與 Statistics 資訊&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;確認&amp;nbsp;IX_Address_StateProvinceID 已經被 Disabled&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;12_Get all indexes and Statistics last updated datetime&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgH0ixVIBNYWagbQF5lPjzG64pNBE2nLf4I7xTZ0FH0Xv29j233vo7Eu1ekH-3NbkbQrcX0Kg27wp4ln5joxtZU8WDkngWX3F0IL-OhIhgn_55uQG2P0PLlvcAbJ9ZHo8qC8P8YBe5HDgo/s1600/12_Get+all+indexes+and+Statistics+last+updated+datetime.png" imageanchor="1"&gt;&lt;img border="0" height="170" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgH0ixVIBNYWagbQF5lPjzG64pNBE2nLf4I7xTZ0FH0Xv29j233vo7Eu1ekH-3NbkbQrcX0Kg27wp4ln5joxtZU8WDkngWX3F0IL-OhIhgn_55uQG2P0PLlvcAbJ9ZHo8qC8P8YBe5HDgo/s640/12_Get+all+indexes+and+Statistics+last+updated+datetime.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
05. 更新&amp;nbsp;Statistics&lt;br /&gt;
&lt;br /&gt;
Update the Statistics of table&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;21_Update the Statistics of table&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxPRLhZxUx_fksOQJv7uyK9fcx2EPe3q3Pqq9u6GZ2H4za3CuxnxF9l3NnS6UmDO2UTyFaR7K_19e3DVo1xZYW50gBpXBI_vF1WWk9oUw2cIZvXyikfHzbtOGkWD7tFWNd3CNQHc69lVQ/s1600/21_Update+the+Statistics+of+table.png" imageanchor="1"&gt;&lt;img border="0" height="234" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxPRLhZxUx_fksOQJv7uyK9fcx2EPe3q3Pqq9u6GZ2H4za3CuxnxF9l3NnS6UmDO2UTyFaR7K_19e3DVo1xZYW50gBpXBI_vF1WWk9oUw2cIZvXyikfHzbtOGkWD7tFWNd3CNQHc69lVQ/s640/21_Update+the+Statistics+of+table.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
06. 觀察 Statistics 資訊&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;確認&amp;nbsp;Statistics 已經被更新&lt;/li&gt;
&lt;li&gt;即便該 Index 早已被 Disabled&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;22_Get all indexes and Statistics last updated datetime&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdiZAX6_mbZKffyZ3-KmaQYf4gKZgIN2GZ55xXCtqlXk5IJtVJngfcuojb3d-ZOG5Q5oXxCltFtwtBOdnNnxQpvdX5dIoEIfDZ8dpZjBZKV82xZYO095zT7I-Hk9-R6EmI8GxsVYq-5_Y/s1600/22_Get+all+indexes+and+Statistics+last+updated+datetime.png" imageanchor="1"&gt;&lt;img border="0" height="170" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdiZAX6_mbZKffyZ3-KmaQYf4gKZgIN2GZ55xXCtqlXk5IJtVJngfcuojb3d-ZOG5Q5oXxCltFtwtBOdnNnxQpvdX5dIoEIfDZ8dpZjBZKV82xZYO095zT7I-Hk9-R6EmI8GxsVYq-5_Y/s640/22_Get+all+indexes+and+Statistics+last+updated+datetime.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
07. 使用 DBCC SHOW_STATISTICS 觀察&amp;nbsp;Statistics&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;確認已經被更新&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;31_DBCC SHOW_STATISTICS&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHMGcxhEnUjmwbTCtzLODGvjK7jUejodtIqjTHgQB3aEmJf9qDFymvZnnMAjHL7PnfOodtLoCJmhVjO61t-s_qTZaE1A1GkwtsouYFRFOq9ID5WjpBB0hFPwlD0wol-5MUaHQ0E28n8hI/s1600/31_DBCC+SHOW_STATISTICS.png" imageanchor="1"&gt;&lt;img border="0" height="296" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHMGcxhEnUjmwbTCtzLODGvjK7jUejodtIqjTHgQB3aEmJf9qDFymvZnnMAjHL7PnfOodtLoCJmhVjO61t-s_qTZaE1A1GkwtsouYFRFOq9ID5WjpBB0hFPwlD0wol-5MUaHQ0E28n8hI/s640/31_DBCC+SHOW_STATISTICS.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
08. 使用 DMV: dm_db_stats_properties 觀察&amp;nbsp;Statistics&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;確認已經被更新&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;32_dm_db_stats_properties&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH6qby_bKirEv9r11hqUVhnivy56Sx9CQtUVhEazlwcRSFaU9VFMgwpzYZSYc4KD1q_3xCbBUW1Ui99ZltqrAL8yTea-mw9XAWSF8CWntCViEvCR5LcUslR3l1FYmBmv_D-CKjJJdGgP8/s1600/32_dm_db_stats_properties.png" imageanchor="1"&gt;&lt;img border="0" height="160" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH6qby_bKirEv9r11hqUVhnivy56Sx9CQtUVhEazlwcRSFaU9VFMgwpzYZSYc4KD1q_3xCbBUW1Ui99ZltqrAL8yTea-mw9XAWSF8CWntCViEvCR5LcUslR3l1FYmBmv_D-CKjJJdGgP8/s640/32_dm_db_stats_properties.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Disabled Index 會防止使用者存取 Index，Query Optimizer 不使用此 Index。&lt;br /&gt;
但 SQL Server 仍會維護與更新該 Index 的統計值。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;Disabled Index&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Disabled Index 會防止使用者存取 Index ，而 Disabled Clustered Index 則會防止存取基礎資料表資料。&amp;nbsp;&lt;/li&gt;
&lt;li&gt;索引定義會保留在中繼資料內，而 index statistics 資料會保留在 Nonclustered Indexes上。&amp;nbsp;&lt;/li&gt;
&lt;li&gt;停用 View 上的 非叢集 或 叢集索引，實際上會刪除 Index Data。&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Disabled Clustered Index，則會防止存取資料；這些資料仍留在資料表中，但無法用於資料操作語言 (DML) 作業，除非 卸除 或 重建索引。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Sample Code&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
20180818_Disabled_Index_Update_Statistics&lt;br /&gt;
&lt;a href="https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing"&gt;https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Reference&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Disable Indexes and Constraints&lt;br /&gt;
&lt;a href="https://docs.microsoft.com/en-us/sql/relational-databases/indexes/disable-indexes-and-constraints?view=sql-server-2017"&gt;https://docs.microsoft.com/en-us/sql/relational-databases/indexes/disable-indexes-and-constraints?view=sql-server-2017&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
STATS_DATE (Transact-SQL)&lt;br /&gt;
&lt;a href="https://docs.microsoft.com/zh-tw/sql/t-sql/functions/stats-date-transact-sql?view=sql-server-2017"&gt;https://docs.microsoft.com/zh-tw/sql/t-sql/functions/stats-date-transact-sql?view=sql-server-2017&lt;/a&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
sys.dm_db_stats_properties (Transact-SQL)&lt;/div&gt;
&lt;div&gt;
&lt;a href="https://docs.microsoft.com/zh-tw/sql/relational-databases/system-dynamic-management-views/sys-dm-db-stats-properties-transact-sql?view=sql-server-2017"&gt;https://docs.microsoft.com/zh-tw/sql/relational-databases/system-dynamic-management-views/sys-dm-db-stats-properties-transact-sql?view=sql-server-2017&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</description><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnBEhheqq5UODPQMvqCoNYbaSymKXKTmQyOIVYqUda75_uHxDE1HAhQqfm6Ut7RWINERm6wLnLStJtKfWpzxb0ShDJ5RYhyphenhyphenoQ26lsRN0fNAPxX56VQUv4qzzt_PYQUuJOZWlWl4H3JxQk/s72-c/22_Get+all+indexes+and+Statistics+last+updated+datetime.png" width="72"/><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><title>Parameter Sniffing: Dynamic SQL, sp_executesql and EXEC (Parameter Sniffing 與 動態 SQL)</title><link>http://sharedderrick.blogspot.com/2018/08/parameter-sniffing-dynamic-sql.html</link><category>Performance Tuning</category><category>SQL Server</category><author>noreply@blogger.com (DerrickLaLa)</author><pubDate>Tue, 14 Aug 2018 20:12:00 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1420955872914622499.post-3322713103938059617</guid><description>&lt;br /&gt;
&lt;br /&gt;
Dynamic SQL: sp_executesql 與 EXEC 有其彈性 與 應用的特殊場合。&lt;br /&gt;
但 Dynamic SQL 需面對 Parameter Sniffing 所帶來的 優點 與 Side Effects。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;table border="1" cellpadding="1" cellspacing="1"&gt;
 &lt;tbody&gt;
&lt;tr&gt;
   &lt;td&gt;&lt;/td&gt;
   &lt;td&gt;Re-Use Execution Plan&lt;/td&gt;
   &lt;td&gt;ObjType&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt;
   &lt;td&gt;Dynamic SQL: EXEC&lt;/td&gt;
   &lt;td&gt;Ad hoc Query - 比對 hash 值&lt;/td&gt;
   &lt;td&gt;&lt;div style="text-align: center;"&gt;
Adhoc&lt;/div&gt;
&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt;
   &lt;td&gt;Dynamic SQL: &lt;span style="color: blue;"&gt;sp_executesql&lt;/span&gt;&lt;/td&gt;
   &lt;td&gt;&lt;span style="color: blue;"&gt;Parameter Sniffing&lt;/span&gt;&lt;/td&gt;
   &lt;td&gt;&lt;div style="text-align: center;"&gt;
Prepared&lt;/div&gt;
&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt;
   &lt;td&gt;Stored Procedure&lt;/td&gt;
   &lt;td&gt;Parameter Sniffing&lt;/td&gt;
   &lt;td&gt;&lt;div style="text-align: center;"&gt;
Proc&lt;/div&gt;
&lt;/td&gt;
  &lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwbs-jWckNJLD2-RQ-iOspYhLoohwH3zW2jxNwRzMtA5zDp4W-j-ElZAowuaNdJQInuv3XOHVDT4En6xiOFCZPWvN4Qw9LNzZ2F9PuJbGycZ4_l04WVwh_EuDFpHyMLYc-sjncVi0lYs4/s1600/62.png" imageanchor="1"&gt;&lt;img border="0" height="238" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwbs-jWckNJLD2-RQ-iOspYhLoohwH3zW2jxNwRzMtA5zDp4W-j-ElZAowuaNdJQInuv3XOHVDT4En6xiOFCZPWvN4Qw9LNzZ2F9PuJbGycZ4_l04WVwh_EuDFpHyMLYc-sjncVi0lYs4/s640/62.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;Dynamic SQL: EXEC&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;採取比對 hash 值&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;相同，就能重複使用&amp;nbsp;Execution Plan。&lt;/li&gt;
&lt;li&gt;不同，產生新的 Execution Plan。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;Dynamic SQL: sp_executesql&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;使用&amp;nbsp;Parameter Sniffing 機制來 Re-Use Execution Plan。&lt;/li&gt;
&lt;li&gt;必須面對 Parameter Sniffing 所帶來的 Side Effects。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
思考&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;sp_executesql，受制於 Parameter Sniffing，導致重複使用效能不佳的 Execution Plan。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
後續文章，將繼續討論 例外情形。&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: large;"&gt;sp_executesql&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;若 Transact-SQL 陳述式本身維持不變，只有 parameters&amp;nbsp; 值改變。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;因此，Query Optimizer 可能會重複使用它針對第 1 次執行所產生的Execution Plan。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;也就是說，當陳述式 parameters&amp;nbsp; 值的變更是唯一的變數時，您可以利用 sp_executesql 取代 Stored Procedure 來重複執行 Transact-SQL 陳述式。&amp;nbsp;&lt;/li&gt;
&lt;li&gt;若要提升效能，請在陳述式字串中使用 完整物件名稱。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
在 sp_executesql 中替換 parameters 的能力，會為利用 EXECUTE 陳述式來執行字串帶來下列好處：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;由於在各次執行之間，sp_executesql 字串中 Transact-SQL 陳述式的實際文字不會改變。&lt;/li&gt;
&lt;li&gt;因此，Query Optimizer 可能會符合第 2 次執行的 Transact-SQL 陳述式與針對第 1 次執行所產生的執行計畫。因此，不需要編譯第 2 個陳述式。&lt;/li&gt;
&lt;li&gt;Transact-SQL 字串只建立一次。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Parameter Sniffing: Dynamic SQL, sp_executesql and EXEC&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Parameter Sniffing 與 動態 SQL&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
01.&amp;nbsp;使用 Dynamic SQL: EXEC&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;執行 10 次。&lt;/li&gt;
&lt;li&gt;傳入參數都不同。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;11_Dynamic SQL_EXEC&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU1tgZXJaf1j-olUR_qEDHBi5YCxpDA_hTxSs8VfvK9kmh1BvK5Bqm6QEgwj7MH4_HsCBSSKqYb8bJZK5TxEhrn5nA6iSrEmLEwjgFhOOkBmCF5vk1xyyY7Z-KbmIif9vxXxD8vr5tFlE/s1600/11_Dynamic+SQL_EXEC.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="282" data-original-width="1290" height="138" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU1tgZXJaf1j-olUR_qEDHBi5YCxpDA_hTxSs8VfvK9kmh1BvK5Bqm6QEgwj7MH4_HsCBSSKqYb8bJZK5TxEhrn5nA6iSrEmLEwjgFhOOkBmCF5vk1xyyY7Z-KbmIif9vxXxD8vr5tFlE/s640/11_Dynamic+SQL_EXEC.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 觀察 Performance Statistics：&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
使用 Dynamic SQL: EXEC&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;如同 Ad hoc Query 一般，Query Optimizer 為每一個 SQL 陳述式建立 hash value，以此 hash value 比對另一 SQL 陳述式的 hash value 是否相同。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;若 hash 值 相同，就能重複使用該 SQL 陳述式所建立 Execution Plan。&lt;/li&gt;
&lt;li&gt;若 hash 值 不同，就必須為該 SQL 陳述式編譯新的 Execution Plan。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;也就是說，要能重複使用 Execution Plan，則執行的 Ad hoc Query 必須完全相同。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;舉例來說，這包含了：空白、註解、大小寫、結尾符號、SET 選項 等。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
觀察&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;RetrievedFromCache 是 true&lt;/li&gt;
&lt;li&gt;Execution Count ，若 hash 值 相同，重複使用 Execution Plan，累加。&lt;/li&gt;
&lt;li&gt;CacheObject 是 Compiled Plan。&lt;/li&gt;
&lt;li&gt;ObjType 是 &lt;span style="color: blue;"&gt;Adhoc&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
Ad hoc Query and Reuse - 重複使用&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2017/11/sql-server-ad-hoc-query-and-reuse.html"&gt;http://sharedderrick.blogspot.com/2017/11/sql-server-ad-hoc-query-and-reuse.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;12_Get last performance statistics&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxE5LMdUeSDZzil9sl_fhNsZITTmU0jbi1wze2GYzO1hQazZcyH7PZ18bOe8CW8CtZfX3ytIt-nJuBHi3fn9nNNyFxgfpgHJ_OPsAz7hdzQXKKNRVMtGUbfhdY6SRDavtKTiOaKM103Q0/s1600/12_Get+last+performance+statistics.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="223" data-original-width="1280" height="110" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxE5LMdUeSDZzil9sl_fhNsZITTmU0jbi1wze2GYzO1hQazZcyH7PZ18bOe8CW8CtZfX3ytIt-nJuBHi3fn9nNNyFxgfpgHJ_OPsAz7hdzQXKKNRVMtGUbfhdY6SRDavtKTiOaKM103Q0/s640/12_Get+last+performance+statistics.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 再度執行 01. 使用 Dynamic SQL: EXEC 後，觀察 Performance Statistics&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Execution Count ，若 hash 值 相同，重複使用 Execution Plan。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;本次範例，已累加到 &lt;span style="color: blue;"&gt;2&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;ObjType 是&amp;nbsp;&lt;span style="color: blue;"&gt;Adhoc&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;13_2_Get last performance statistics&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9EpTF_npNrcMacPQkPgQeNmiTs3JoaZiVdBmBgc4xfrTCOc56-dIZ11pfXX8Etc-nunpqn6DFUVeL3_xGK-nfqh4kpZgsyOoP0pWt46iEG0GqbfCJDrlqHeNwXwMPzSz7DUDrUfGzClM/s1600/13_2_Get+last+performance+statistics.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="216" data-original-width="1362" height="100" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9EpTF_npNrcMacPQkPgQeNmiTs3JoaZiVdBmBgc4xfrTCOc56-dIZ11pfXX8Etc-nunpqn6DFUVeL3_xGK-nfqh4kpZgsyOoP0pWt46iEG0GqbfCJDrlqHeNwXwMPzSz7DUDrUfGzClM/s640/13_2_Get+last+performance+statistics.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
04. 使用&amp;nbsp;Dynamic SQL: sp_executesql&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;執行 10 次。&lt;/li&gt;
&lt;li&gt;傳入參數都不同。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;21_Dynamic SQL_sp_executesql&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZdpBAyrysRaJ1MYu8XbgCCI08UXn7MN66MfwDbFl-dgiIFnNnxi0tWdB24Af3OwknZi3hbRh-5JOVt3unVUr2QYLmGp4dhOUeHzeG6Lo7MRqMujXKnRYWYBnpIpM67MtzvpbOGd-1K5A/s1600/21_Dynamic+SQL_sp_executesql.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="282" data-original-width="1019" height="177" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZdpBAyrysRaJ1MYu8XbgCCI08UXn7MN66MfwDbFl-dgiIFnNnxi0tWdB24Af3OwknZi3hbRh-5JOVt3unVUr2QYLmGp4dhOUeHzeG6Lo7MRqMujXKnRYWYBnpIpM67MtzvpbOGd-1K5A/s640/21_Dynamic+SQL_sp_executesql.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
05. 觀察 Performance Statistics：&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
使用&amp;nbsp;Dynamic SQL: sp_executesql&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Parameter Sniffing: Re-Use Execution Plan。&lt;/li&gt;
&lt;li&gt;僅第 1 次 有編譯產生 Execution Plan，之後都是共用同一份 Execution Plan。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
觀察&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;TSQL 是「&lt;span style="color: blue;"&gt;Parameterization&lt;/span&gt;(參數化)」&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;(@StateProvinceID INT)SELECT City FROM Person.Address WHERE StateProvinceID = @StateProvinceID&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;RetrievedFromCache 是 true&lt;/li&gt;
&lt;li&gt;由於 Parameter Sniffing 發揮功能，重複使用同一份 Execution Plan。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;本次範例 Execution Count，已經累加到 &lt;span style="color: blue;"&gt;10&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;CacheObject 是 Compiled Plan。&lt;/li&gt;
&lt;li&gt;ObjType 是 &lt;span style="color: purple;"&gt;Prepared&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;22_Get last performance statistics&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMRZdWGBz5SeRAtyfr4BP47oENg6NWMg6K84OVyP8gUhzPgyCY3W2OTVdh7T5ZhgVGaHKByX0L2HCsArSib952tY7cDqgVcmnTXCe7waWI9YmujpG7xTmlViqlb07Xs0g9WnT_LdZih8s/s1600/22_Get+last+performance+statistics.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="85" data-original-width="1546" height="34" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMRZdWGBz5SeRAtyfr4BP47oENg6NWMg6K84OVyP8gUhzPgyCY3W2OTVdh7T5ZhgVGaHKByX0L2HCsArSib952tY7cDqgVcmnTXCe7waWI9YmujpG7xTmlViqlb07Xs0g9WnT_LdZih8s/s640/22_Get+last+performance+statistics.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
06.&amp;nbsp;再度執行 使用 Dynamic SQL: sp_executesql 後，觀察 Performance Statistics&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;由於 Parameter Sniffing 發揮功能，重複使用同一份 Execution Plan。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;本次範例 Execution Count，已經累加到&amp;nbsp;2&lt;span style="color: blue;"&gt;0&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;ObjType 是 &lt;span style="color: purple;"&gt;Prepared&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;23_2nd_Get last performance statistics&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRk-K5aBDqLXNH0tkYQ_f5YkTSNLVwV1HRqDEiNPJNJp_XuEGKVd3AzSB36XOxzu9kVw2VNe2ZIxR_nREDfpqAr19YFYu-ErYbgphHnfFzXNCv9k77_WDxCWuiIUAOOgaWFxqfOi8HM6s/s1600/23_2nd_Get+last+performance+statistics.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="74" data-original-width="972" height="48" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRk-K5aBDqLXNH0tkYQ_f5YkTSNLVwV1HRqDEiNPJNJp_XuEGKVd3AzSB36XOxzu9kVw2VNe2ZIxR_nREDfpqAr19YFYu-ErYbgphHnfFzXNCv9k77_WDxCWuiIUAOOgaWFxqfOi8HM6s/s640/23_2nd_Get+last+performance+statistics.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Proc and Dynamic SQL:&amp;nbsp;sp_executesql, EXEC&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
01. 建立 Stored Procedure:&amp;nbsp;Proc and Dynamic SQL: EXEC&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;在 Proc 內使用 Dynamic SQL: EXEC&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;31_Proc and Dynamic SQL_EXEC&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvnWLLy1brybRuLYXCIPn7mDJhilvk2PSx5C7DU9u9GGKX0B_vTwhf3ZcTRgecK37ccQToUBxeQaUCxvWNtkLDFMonrMis030XqeKMzyEBEb67euawDilxNXw-_GVbIrJuvfqvbICErng/s1600/31_Proc+and+Dynamic+SQL_EXEC.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="290" data-original-width="1296" height="142" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvnWLLy1brybRuLYXCIPn7mDJhilvk2PSx5C7DU9u9GGKX0B_vTwhf3ZcTRgecK37ccQToUBxeQaUCxvWNtkLDFMonrMis030XqeKMzyEBEb67euawDilxNXw-_GVbIrJuvfqvbICErng/s640/31_Proc+and+Dynamic+SQL_EXEC.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 執行 Proc_DynamicSQL_EXEC&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;執行 10 次。&lt;/li&gt;
&lt;li&gt;傳入參數都不同。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;32_Exec_Proc_DynamicSQL_EXEC&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1dqgSZZRg7zdVmu_UYwWzQbq0NUSa-UyQdvJ2B8d6q5QXbT7pxxbH4HTeODTmBwLPIhBeGSoLupFV6WmdIuR94J2ZLOBIHc327ldOmXWL8SxKLuJACJjsa7LDfRE0fjD-fI96jsgb-Rg/s1600/32_Exec_Proc_DynamicSQL_EXEC.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="206" data-original-width="441" height="298" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1dqgSZZRg7zdVmu_UYwWzQbq0NUSa-UyQdvJ2B8d6q5QXbT7pxxbH4HTeODTmBwLPIhBeGSoLupFV6WmdIuR94J2ZLOBIHc327ldOmXWL8SxKLuJACJjsa7LDfRE0fjD-fI96jsgb-Rg/s640/32_Exec_Proc_DynamicSQL_EXEC.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 觀察 Performance Statistics：&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
在 Proc 內使用 Dynamic SQL: EXEC&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;如同 Ad hoc Query 一般，Query Optimizer 為每一個 SQL 陳述式建立 hash value，以此 hash value 比對另一 SQL 陳述式的 hash value 是否相同。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;若 hash 值 相同，就能重複使用該 SQL 陳述式所建立 Execution Plan。&lt;/li&gt;
&lt;li&gt;若 hash 值 不同，就必須為該 SQL 陳述式編譯新的 Execution Plan。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;也就是說，要能重複使用 Execution Plan，則執行的 Ad hoc Query 必須完全相同。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;舉例來說，這包含了：空白、註解、大小寫、結尾符號、SET 選項 等。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
觀察&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;RetrievedFromCache 是 true&lt;/li&gt;
&lt;li&gt;Execution Count ，若 hash 值 相同，重複使用 Execution Plan，累加。&lt;/li&gt;
&lt;li&gt;CacheObject 是 Compiled Plan。&lt;/li&gt;
&lt;li&gt;ObjType 是 &lt;span style="color: blue;"&gt;Adhoc&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;33_Get last performance statistics&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYzwtzBeY1VEpFn1tUpcU8IfADmxFeZnrjclUm_3NUYSvwhF6olf9H9xoRTn6vGa267Qoydnr5m-aKLk8N7Uvk-pF0rZ22kBQEfM3Y21gRaEIrSqbMBjuPu-iVTLZhTGHd3U6ezCjbphY/s1600/33_Get+last+performance+statistics.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="235" data-original-width="1354" height="110" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYzwtzBeY1VEpFn1tUpcU8IfADmxFeZnrjclUm_3NUYSvwhF6olf9H9xoRTn6vGa267Qoydnr5m-aKLk8N7Uvk-pF0rZ22kBQEfM3Y21gRaEIrSqbMBjuPu-iVTLZhTGHd3U6ezCjbphY/s640/33_Get+last+performance+statistics.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
04. 再度執行 02. 執行 Proc_DynamicSQL_EXEC 後，觀察 Performance Statistics&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Execution Count ，若 hash 值 相同，重複使用 Execution Plan。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;本次範例，已累加到&amp;nbsp;&lt;span style="color: blue;"&gt;2&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;ObjType 是&amp;nbsp;&lt;span style="color: blue;"&gt;Adhoc&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;34_2nd_Get last performance statistics&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgi42t29br7ADzQNvSCHzXhQYDjvIfiDxjZkqpq1DkGelK5l_tm1tw6F_EjwGKsGdIgfe3rhtk_qMfJhhTFQmHb-eTBp-y_NGvqJmFFIaA5MhgCBYUXrRMzgYsRN1OUOXITthN-Qf92nVo/s1600/34_2nd_Get+last+performance+statistics.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="242" data-original-width="1349" height="114" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgi42t29br7ADzQNvSCHzXhQYDjvIfiDxjZkqpq1DkGelK5l_tm1tw6F_EjwGKsGdIgfe3rhtk_qMfJhhTFQmHb-eTBp-y_NGvqJmFFIaA5MhgCBYUXrRMzgYsRN1OUOXITthN-Qf92nVo/s640/34_2nd_Get+last+performance+statistics.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
05. 建立 Stored Procedure:&amp;nbsp;Proc_DynamicSQL_sp_executesql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;在 Proc 內使用 Dynamic SQL: sp_executesql&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;41_Proc and Dynamic SQL_sp_executesql&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhno9Y0VraWOboYEytVvdNL853Y56ck6vXmlbTp5t8zFJXNVGT6c4lC3Qb3DKNioyO-s7pFjPZ3LJeH2rp2cZmLT_wihWChg8WXRop0Bwp6YL1IWfudj3BRu3trUp45zv8ZBq-8cztr7k4/s1600/41_Proc+and+Dynamic+SQL_sp_executesql.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="260" data-original-width="1027" height="162" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhno9Y0VraWOboYEytVvdNL853Y56ck6vXmlbTp5t8zFJXNVGT6c4lC3Qb3DKNioyO-s7pFjPZ3LJeH2rp2cZmLT_wihWChg8WXRop0Bwp6YL1IWfudj3BRu3trUp45zv8ZBq-8cztr7k4/s640/41_Proc+and+Dynamic+SQL_sp_executesql.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
06. 執行 Proc_DynamicSQL_sp_executesql&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;執行 10 次。&lt;/li&gt;
&lt;li&gt;傳入參數都不同。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;42_Exec_Proc_DynamicSQL_sp_executesql&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8ySyDS7is-vI-FGrJFnE28bJjPUoPQDNXJ1mFZeLLmIFj9zGHJDTsgjeRH9AskcwM128q7VB2NKatuSPi4aGyr3Qe-6p-mjWWXL7u9d-aXvMJJtX62y9OR0-pYolH-ofvgcpQ8ZN6UOU/s1600/42_Exec_Proc_DynamicSQL_sp_executesql.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="206" data-original-width="545" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8ySyDS7is-vI-FGrJFnE28bJjPUoPQDNXJ1mFZeLLmIFj9zGHJDTsgjeRH9AskcwM128q7VB2NKatuSPi4aGyr3Qe-6p-mjWWXL7u9d-aXvMJJtX62y9OR0-pYolH-ofvgcpQ8ZN6UOU/s640/42_Exec_Proc_DynamicSQL_sp_executesql.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
07. 觀察 Performance Statistics：&lt;br /&gt;
&lt;br /&gt;
在 Proc 內使用 Dynamic SQL: sp_executesql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Parameter Sniffing: Re-Use Execution Plan&lt;/li&gt;
&lt;li&gt;僅第 1 次 有編譯產生 Execution Plan，之後都是共用同一份 Execution Plan。&lt;/li&gt;
&lt;li&gt;執行 10 次，即便是輸入不同的參數值，都是共用同一份 Execution Plan。&lt;/li&gt;
&lt;li&gt;節省 編譯 Execution Plan 的資源。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
觀察&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;TSQL 是「&lt;span style="color: blue;"&gt;Parameterization&lt;/span&gt;(參數化)」&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;(@StateProvinceID INT)SELECT City FROM Person.Address WHERE StateProvinceID = @StateProvinceID&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;RetrievedFromCache 是 true&lt;/li&gt;
&lt;li&gt;由於 Parameter Sniffing 發揮功能，重複使用同一份 Execution Plan。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;本次範例 Execution Count，已經累加到 &lt;span style="color: blue;"&gt;10&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;CacheObject 是 Compiled Plan。&lt;/li&gt;
&lt;li&gt;ObjType 是 &lt;span style="color: purple;"&gt;&lt;b&gt;Prepared&lt;/b&gt;&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;43_Get last performance statistics&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioieGect-epMCA-PzsLnR5f2NvPhw26tSXzjiob3pL-HgF5RNzwPCRm0RerxCJbpg1W0zzZseo1C3iTW0QkUvgYbVbJudNrgn7VbwJJ4jlqh4PCUQk_0AR9eapkaN9eXinssBIZ3y7M3g/s1600/43_Get+last+performance+statistics.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="94" data-original-width="1551" height="38" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioieGect-epMCA-PzsLnR5f2NvPhw26tSXzjiob3pL-HgF5RNzwPCRm0RerxCJbpg1W0zzZseo1C3iTW0QkUvgYbVbJudNrgn7VbwJJ4jlqh4PCUQk_0AR9eapkaN9eXinssBIZ3y7M3g/s640/43_Get+last+performance+statistics.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
08. 再度執行 06. 執行 Proc_DynamicSQL_sp_executesql&amp;nbsp;後，觀察 Performance Statistics&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;由於 Parameter Sniffing 發揮功能，重複使用同一份 Execution Plan。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;本次範例 Execution Count，已經累加到&amp;nbsp;2&lt;span style="color: blue;"&gt;0&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;ObjType 是&amp;nbsp;&lt;b&gt;&lt;span style="color: purple;"&gt;Prepared&lt;/span&gt;&lt;/b&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;44_2nd_Get last performance statistics&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijCzDftELEqweJ1uti6e4FAXUIznTCjl_t_r_Q7uYrgValQiJ-VOtlFF1IQd12geEG4JsrHCPHJWgdfG3DFJSu7QvsfxmVw03Q5jE1nMRb3zBH0ldO5Y63TnEyBIdTdNY7nN-osdXL5FI/s1600/44_2nd_Get+last+performance+statistics.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="93" data-original-width="1546" height="38" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijCzDftELEqweJ1uti6e4FAXUIznTCjl_t_r_Q7uYrgValQiJ-VOtlFF1IQd12geEG4JsrHCPHJWgdfG3DFJSu7QvsfxmVw03Q5jE1nMRb3zBH0ldO5Y63TnEyBIdTdNY7nN-osdXL5FI/s640/44_2nd_Get+last+performance+statistics.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;對照組&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;51_Proc without Dynamic SQL&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5LyQz1OopHKI5UHhBY7uMcXLoFOrFVIftZ5l8-Sdzk8wBMiWNzHpZw9dhZr81T1bO2twFLBlDkm5b16dFv-_ukWTa1fiCvxN4YMhuyD9NjoDlErkwjYKP15ff_28L3oSKgsoimXled5g/s1600/51_Proc+without+Dynamic+SQL.png" imageanchor="1"&gt;&lt;img border="0" height="178" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5LyQz1OopHKI5UHhBY7uMcXLoFOrFVIftZ5l8-Sdzk8wBMiWNzHpZw9dhZr81T1bO2twFLBlDkm5b16dFv-_ukWTa1fiCvxN4YMhuyD9NjoDlErkwjYKP15ff_28L3oSKgsoimXled5g/s640/51_Proc+without+Dynamic+SQL.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;52_Exec_Proc_NonDynamicSQL&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqohIjxmvgqYNizQe4-poTGIOK2ZYcDV3IKXRlGBt471_33rByCCFGf2UrQAuTZn3FsI7Wdv4SExS_Pi_3cz3fqi1xLxG16iZRGtUsM59wtKrByZVtJdXoFCuc1sOoLrEs3rcUDsE6s7Y/s1600/52_Exec_Proc_NonDynamicSQL.png" imageanchor="1"&gt;&lt;img border="0" height="316" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqohIjxmvgqYNizQe4-poTGIOK2ZYcDV3IKXRlGBt471_33rByCCFGf2UrQAuTZn3FsI7Wdv4SExS_Pi_3cz3fqi1xLxG16iZRGtUsM59wtKrByZVtJdXoFCuc1sOoLrEs3rcUDsE6s7Y/s640/52_Exec_Proc_NonDynamicSQL.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;53_Get last performance statistics&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVXLHDS6jig-DqgfdkfJKcYKn1_x0wqin2zeM-IU-fif0yZW0rFpL2Z5UyfeEjHtpDUQs0Fy4UTGmGA5CzE7g8m_UDmcC0vK5icSYXNTyeoc8ZPWEQxrgkLxmL3di-nlnRKrF_nOYN85k/s1600/53_Get+last+performance+statistics.png" imageanchor="1"&gt;&lt;img border="0" height="48" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVXLHDS6jig-DqgfdkfJKcYKn1_x0wqin2zeM-IU-fif0yZW0rFpL2Z5UyfeEjHtpDUQs0Fy4UTGmGA5CzE7g8m_UDmcC0vK5icSYXNTyeoc8ZPWEQxrgkLxmL3di-nlnRKrF_nOYN85k/s640/53_Get+last+performance+statistics.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;54_2nd_Get last performance statistics&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhU0_0xpB-rOz49vkwHwD5Wd3FWveRue9ocNo4mHMRo-xoCchj0aoRT_UVzGUErg3VNZoqOgfZs06211uDFkvaFC8RF8OUqZn4IkllK0BqYrZ5z8V2BR8tz1AqpCMu-A_QSdD9v1MsTzfA/s1600/54_2nd_Get+last+performance+statistics.png" imageanchor="1"&gt;&lt;img border="0" height="48" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhU0_0xpB-rOz49vkwHwD5Wd3FWveRue9ocNo4mHMRo-xoCchj0aoRT_UVzGUErg3VNZoqOgfZs06211uDFkvaFC8RF8OUqZn4IkllK0BqYrZ5z8V2BR8tz1AqpCMu-A_QSdD9v1MsTzfA/s640/54_2nd_Get+last+performance+statistics.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
很單純的 Proc，沒有使用 Dynamic SQL&lt;br /&gt;
&lt;br /&gt;
Parameter Sniffing: Re-Use Execution Plan&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;僅第 1 次 有編譯產生 Execution Plan，之後都是共用同一份 Execution Plan。&lt;/li&gt;
&lt;li&gt;執行 10 次，即便是輸入不同的參數值，都是共用同一份 Execution Plan。&lt;/li&gt;
&lt;li&gt;節省 編譯 Execution Plan 的資源。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
觀察&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;RetrievedFromCache 是 true&lt;/li&gt;
&lt;li&gt;由於 Parameter Sniffing 發揮功能，重複使用同一份 Execution Plan。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;Execution Count，已經累加。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;CacheObject 是 Compiled Plan。&lt;/li&gt;
&lt;li&gt;ObjType 是 &lt;span style="color: blue;"&gt;Proc&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Sample Code&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
20180814_Parameter_Sniffing_Dynamic_SQL&lt;br /&gt;
&lt;a href="https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing"&gt;https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Reference&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Parameter Sniffing: Pros and Cons, 參數探測&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2017/12/sql-server-parameter-sniffing-pros-and.html"&gt;http://sharedderrick.blogspot.com/2017/12/sql-server-parameter-sniffing-pros-and.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Parameter Sniffing: sp_recompile, WITH RECOMPILE&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/01/sql-server-parameter-sniffing.html"&gt;http://sharedderrick.blogspot.com/2018/01/sql-server-parameter-sniffing.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Compare "WITH RECOMPILE / sp_recompile" with "OPTION RECOMPILE"&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/02/sql-server-compare-with-recompile-with.html"&gt;http://sharedderrick.blogspot.com/2018/02/sql-server-compare-with-recompile-with.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Enable optimize for ad hoc workloads , 針對特定工作負載最佳化&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2017/11/sql-server-enable-optimize-for-ad-hoc.html"&gt;http://sharedderrick.blogspot.com/2017/11/sql-server-enable-optimize-for-ad-hoc.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Ad hoc Query and Reuse - 重複使用&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2017/11/sql-server-ad-hoc-query-and-reuse.html"&gt;http://sharedderrick.blogspot.com/2017/11/sql-server-ad-hoc-query-and-reuse.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Dynamic SQL - 動態 SQL&lt;br /&gt;
&lt;a href="https://docs.microsoft.com/zh-tw/sql/odbc/reference/dynamic-sql?view=sql-server-2017"&gt;https://docs.microsoft.com/zh-tw/sql/odbc/reference/dynamic-sql?view=sql-server-2017&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Static SQL - 靜態 SQL&lt;br /&gt;
&lt;a href="https://docs.microsoft.com/zh-tw/sql/odbc/reference/static-sql?view=sql-server-2017"&gt;https://docs.microsoft.com/zh-tw/sql/odbc/reference/static-sql?view=sql-server-2017&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
sp_executesql (Transact-SQL)&lt;br /&gt;
&lt;a href="https://docs.microsoft.com/zh-tw/sql/relational-databases/system-stored-procedures/sp-executesql-transact-sql?view=sql-server-2017"&gt;https://docs.microsoft.com/zh-tw/sql/relational-databases/system-stored-procedures/sp-executesql-transact-sql?view=sql-server-2017&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
EXECUTE (Transact-SQL)&lt;br /&gt;
&lt;a href="https://docs.microsoft.com/zh-tw/sql/t-sql/language-elements/execute-transact-sql?view=sql-server-2017"&gt;https://docs.microsoft.com/zh-tw/sql/t-sql/language-elements/execute-transact-sql?view=sql-server-2017&lt;/a&gt;</description><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwbs-jWckNJLD2-RQ-iOspYhLoohwH3zW2jxNwRzMtA5zDp4W-j-ElZAowuaNdJQInuv3XOHVDT4En6xiOFCZPWvN4Qw9LNzZ2F9PuJbGycZ4_l04WVwh_EuDFpHyMLYc-sjncVi0lYs4/s72-c/62.png" width="72"/><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><title>TSQL: Look at parameter from execution plan, 查看 執行計畫 所使用的參數</title><link>http://sharedderrick.blogspot.com/2018/07/tsql-look-at-parameter-from-execution.html</link><author>noreply@blogger.com (DerrickLaLa)</author><pubDate>Mon, 30 Jul 2018 22:10:00 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1420955872914622499.post-6834398632091019969</guid><description>&lt;br /&gt;
&lt;br /&gt;
延續 先前文章 &lt;a href="http://sharedderrick.blogspot.com/2017/12/sql-server-look-at-parameter-from.html"&gt;SSMS: Look at parameter from execution plan, 查看 執行計畫 所使用的參數&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
在對 Stored Procedure 執行 Performance Optimization (效能優化)時，若能知道編譯時期的 &lt;span style="color: blue;"&gt;&lt;b&gt;Parameter Compiled Value&lt;/b&gt;&lt;/span&gt;，將能夠精準有效率的執行優化任務。&lt;br /&gt;
&lt;br /&gt;
可使用以下方式查詢：Parameter Compiled Value&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;使用 SSMS&lt;/li&gt;
&lt;li&gt;使用&amp;nbsp;DMV: sys.dm_exec_query_plan&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
使用 SSMS 觀察 Execution Plan，可以看到&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Column&lt;/li&gt;
&lt;li&gt;Parameter Compiled Value&lt;/li&gt;
&lt;li&gt;Parameter Data Type&lt;/li&gt;
&lt;li&gt;Parameter Runtime Value&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
使用 DMV: sys.dm_exec_query_plan 的資料行: query_plan，可以觀察 &lt;b&gt;&lt;span style="color: blue;"&gt;ParameterList &lt;/span&gt;&lt;/b&gt;Element(元素)：&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Column: 傳入的 Parameter 名稱。&lt;/li&gt;
&lt;li&gt;ParameterDataType: 使用的資料類型。&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;ParameterCompiledValue&lt;/span&gt;&lt;/b&gt;: 編譯 Execution Plan 的值。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQZqUkS97vsEuNtEPYKkuPVf9mqoDw06CJOlUlX9xaO7ftyiNr4sJdVnrleRiZbZiS_T6YNRcPuawtRWf2smGRKjsbjHvAqskY2kauZ16FQEdP429qqOMUKQK9waGAy86FaPD5P010UNs/s1600/02_XML_ParameterList.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="159" data-original-width="1162" height="86" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQZqUkS97vsEuNtEPYKkuPVf9mqoDw06CJOlUlX9xaO7ftyiNr4sJdVnrleRiZbZiS_T6YNRcPuawtRWf2smGRKjsbjHvAqskY2kauZ16FQEdP429qqOMUKQK9waGAy86FaPD5P010UNs/s640/02_XML_ParameterList.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq8VlrMxcU4LSdO8JLE_A09aUrLJT5ok2rx6fuuJ0Nf9MvhfdwrPoEi3mTnFlM57IILNLvx2CdMIx5MyTwTC-w5_f4Rlq2zhc1XKKKnqab1Fy5i6tyfIzSazB1LczJpMa0OYTIwNiQeX0/s1600/12_last+performance+statistics_ParameterList.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="132" data-original-width="710" height="118" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq8VlrMxcU4LSdO8JLE_A09aUrLJT5ok2rx6fuuJ0Nf9MvhfdwrPoEi3mTnFlM57IILNLvx2CdMIx5MyTwTC-w5_f4Rlq2zhc1XKKKnqab1Fy5i6tyfIzSazB1LczJpMa0OYTIwNiQeX0/s640/12_last+performance+statistics_ParameterList.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;TSQL: Look at parameter from execution plan, 查&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;看 執行計畫 所使用的參數&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
01. 使用以下範例，其中：&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;[dbo].[uspGetWhereUsedProductID] 使用的參數是：&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;@StartProductID=819&lt;/li&gt;
&lt;li&gt;@CheckDate='2010-12-23'&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;01_TSQL_Sample&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi01CmqnmzF2UD9iAowbCIdBL_ounbXbAEcrOhXw4tYvGHOivutCafM5AR0NnebHT_QypAZolncfuHB8O2hdA-m_6vzeKdSWbrnvcSu5hK7MAxlDaoYOmHh5t78GcATY7aEckB8sWVBf2Y/s1600/01_TSQL_Sample.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="374" data-original-width="954" height="250" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi01CmqnmzF2UD9iAowbCIdBL_ounbXbAEcrOhXw4tYvGHOivutCafM5AR0NnebHT_QypAZolncfuHB8O2hdA-m_6vzeKdSWbrnvcSu5hK7MAxlDaoYOmHh5t78GcATY7aEckB8sWVBf2Y/s640/01_TSQL_Sample.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 使用以下語法查詢取得 last performance statistics for cached query:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: sql"&gt;-- Get last performance statistics for cached query: Execution Count, Plan Recompile, ParameterList, Query Plan, etc.
SELECT TOP 10 st.text [TSQL], DB_NAME(st.dbid) [DB], 
 qs.last_elapsed_time/1000000.0 [LastElapsedTime(sec)],
 qs.last_worker_time/1000000.0 [LastCPUTime(sec)],
 qs.last_logical_reads LastLogicalReads,
 qs.last_physical_reads LastPhysicalRead,
 qs.last_logical_writes LastlogicalWrites,
 qs.last_rows LastRows,
 cp.usecounts [ExecutionCount], cp.size_in_bytes/1024.0 [PlanSize(KB)],
 cp.cacheobjtype [CacheObject], cp.objtype [ObjType], qs.plan_generation_num [PlanRecompile],
 qp.query_plan.query('declare namespace ns="http://schemas.microsoft.com/sqlserver/2004/07/showplan";
 (/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/ns:QueryPlan/ns:ParameterList/ns:ColumnReference[@Column])') [ParameterList],
 qp.query_plan [QueryPlan], cp.plan_handle, qs.last_execution_time, qs.creation_time
FROM sys.dm_exec_cached_plans cp INNER JOIN sys.dm_exec_query_stats qs
         ON cp.plan_handle = qs.plan_handle
 CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) st
 CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) qp
WHERE st.dbid = DB_ID('AdventureWorks2014')
-- CHARINDEX ('Products', st.text) &amp;gt;0
-- st.text LIKE '%xxx%'
ORDER BY [ExecutionCount] DESC;
GO
&lt;/pre&gt;
&lt;br /&gt;
-- figure&amp;nbsp;11_Get last performance statistics for cached query&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWVsLcJiRBM0d3cOq0FQ5WdrjWyK8pgZ2CdrHWVwiL7WyOy7lpQMZABpPn-lzv9xNW1KWhfoDkNOdEfsSKxeqMP6I-sVkR1xJIlA0aAxaBqy3L6wgAH0li9x3K6Ccm27lz-IfLqXYKrAg/s1600/11_Get+last+performance+statistics+for+cached+query.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="542" data-original-width="1600" height="216" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWVsLcJiRBM0d3cOq0FQ5WdrjWyK8pgZ2CdrHWVwiL7WyOy7lpQMZABpPn-lzv9xNW1KWhfoDkNOdEfsSKxeqMP6I-sVkR1xJIlA0aAxaBqy3L6wgAH0li9x3K6Ccm27lz-IfLqXYKrAg/s640/11_Get+last+performance+statistics+for+cached+query.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 檢視 查詢結果，可以看到：[ParameterList]。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;考量會傳入多個參數值，採用 XML 格式呈現。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
-- figure&amp;nbsp;12_last performance statistics_ParameterList&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwWYFgVW-LaSTq4XTH5odGqnjHadKa3adL9AEkxvSyzCi1j3gLlYdacmpi6H4I05EAPbqO6rM_3yiPBnL0b_qXGs2HAbQJtMgyhAfA7aCupdOZ-U_gTA409A3_mZ6hKCSLqsi8i7Omwbg/s1600/12_last+performance+statistics_ParameterList.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="132" data-original-width="710" height="118" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwWYFgVW-LaSTq4XTH5odGqnjHadKa3adL9AEkxvSyzCi1j3gLlYdacmpi6H4I05EAPbqO6rM_3yiPBnL0b_qXGs2HAbQJtMgyhAfA7aCupdOZ-U_gTA409A3_mZ6hKCSLqsi8i7Omwbg/s640/12_last+performance+statistics_ParameterList.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
04. 檢查 ParameterList 的 XML 格式，可以觀察'：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Column: 傳入的 Parameter 名稱。&lt;/li&gt;
&lt;li&gt;ParameterDataType: 使用的資料類型。&lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;ParameterCompiledValue&lt;/b&gt;&lt;/span&gt;: 編譯 Execution Plan 的值。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;pre class="brush: sql"&gt;Column="@CheckDate" ParameterDataType="datetime" ParameterCompiledValue="'2010-12-23 00:00:00.000'"
Column="@StartProductID" ParameterDataType="int" ParameterCompiledValue="(819)"
&lt;/pre&gt;
&lt;br /&gt;
-- figure&amp;nbsp;13_Review_ParameterCompiledValue&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWpcVi4f-MNV2w9vGp53Ekj7b1Vp9etBZ0O-MALQv_N8H9SJ7qFVP0fuZ8cVQqKX2focOKWOHWuE_eDuivm8sqiLgZDiajPxwKMT1eNcMEkYIUJCGN_F_IxTU0kOLVAvBh-kHCGdjpoFU/s1600/13_Review_ParameterCompiledValue.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="141" data-original-width="1436" height="62" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWpcVi4f-MNV2w9vGp53Ekj7b1Vp9etBZ0O-MALQv_N8H9SJ7qFVP0fuZ8cVQqKX2focOKWOHWuE_eDuivm8sqiLgZDiajPxwKMT1eNcMEkYIUJCGN_F_IxTU0kOLVAvBh-kHCGdjpoFU/s640/13_Review_ParameterCompiledValue.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
05. Get performance statistics for cached query - Full&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: sql"&gt;-- Get performance statistics for cached query - Full
/*
sys.dm_exec_query_stats - Returns aggregate performance statistics
An initial query of sys.dm_exec_query_stats might produce inaccurate results if there is a workload currently executing on the server. 
More accurate results may be determined by rerunning the query.

total_elapsed_time: Total elapsed time, reported in microseconds (but only accurate to milliseconds), 
for completed executions of this plan.
*/

SELECT TOP 10 st.text [TSQL], DB_NAME(st.dbid) [DB], cp.usecounts [ExecutionCount],
 qs.total_elapsed_time/cp.usecounts/1000000.0 [AvgElapsedTime(sec)], 
 qs.last_elapsed_time/1000000.0 [LastElapsedTime(sec)], qs.max_elapsed_time/1000000.0 [MaxElapsedTime(sec)], 
 qs.min_elapsed_time/1000000.0 [MinElapsedTime(sec)], qs.total_elapsed_time/1000000.0 [TotalElapsedTime(sec)],
 qs.total_worker_time/cp.usecounts/1000000.0 [AvgCPUTime(sec)], 
 qs.last_worker_time/1000000.0 [LastCPUTime(sec)], qs.max_worker_time/1000000.0 [MaxCPUTime(sec)], 
 qs.min_worker_time/1000000.0 [MinCPUTime(sec)], qs.total_worker_time/1000000.0 [TotalCPUTime(sec)], 
 qs.total_logical_reads/cp.usecounts [AvgLogicalRead], 
 qs.last_logical_reads, qs.max_logical_reads, qs.min_logical_reads, qs.total_logical_reads, 
 qs.last_physical_reads [LastPhysicalRead], qs.max_physical_reads, qs.min_physical_reads, qs.total_physical_reads,  
 qs.total_logical_writes/cp.usecounts [AvgLogicalWrite], qs.last_logical_writes,
 qs.max_logical_writes, qs.min_logical_writes, qs.total_logical_writes,
 qs.last_rows [LastRows], qs.max_rows, qs.min_rows, qs.total_rows,
 qp.query_plan.query('declare namespace ns="http://schemas.microsoft.com/sqlserver/2004/07/showplan";
 (/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/ns:QueryPlan/ns:ParameterList/ns:ColumnReference[@Column])') [ParameterList], 
 qp.query_plan [QueryPlan], cp.plan_handle, cp.size_in_bytes/1024.0 [PlanSize(KB)],
 cp.cacheobjtype [CacheObject], cp.objtype [ObjType], qs.plan_generation_num [PlanRecompile],
 st.objectid, qs.last_execution_time, qs.creation_time --qs.*
FROM sys.dm_exec_cached_plans cp INNER JOIN sys.dm_exec_query_stats qs
         ON cp.plan_handle = qs.plan_handle
 CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) st
 CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) qp
WHERE st.dbid = DB_ID('AdventureWorks2014')
-- CHARINDEX ('Products', st.text) &amp;gt;0
-- st.text LIKE '%xxx%'
ORDER BY [ExecutionCount] DESC;
GO

/*
CPU bound - ORDER BY qs.total_worker_time , [AvgElapsedTime(sec)]
I/O bound - ORDER BY qs.total_logical_reads , [AvgLogicalRead]
*/

&lt;/pre&gt;
&lt;br /&gt;
-- figure&amp;nbsp;21_Get performance statistics for cached query&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjryZhKZl_7KZUYFEbZFcuMI-FzmJ7bibaGCbc97VAMvNgLAGv450ijxTwig6zuI_i-oh0LJQyD_D9wUC2SqXkaH1mBTe2F_PIsDJMfvTgKxq7tAHihSfjaBaPhtDqBefGEMzx8-kDV_Vg/s1600/21_Get+performance+statistics+for+cached+query.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="656" data-original-width="1600" height="262" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjryZhKZl_7KZUYFEbZFcuMI-FzmJ7bibaGCbc97VAMvNgLAGv450ijxTwig6zuI_i-oh0LJQyD_D9wUC2SqXkaH1mBTe2F_PIsDJMfvTgKxq7tAHihSfjaBaPhtDqBefGEMzx8-kDV_Vg/s640/21_Get+performance+statistics+for+cached+query.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
06. 檢視 回傳 的結果：&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;22_Get performance statistics for cached query&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuABYgNcpAYA5kDXJPLyIHnXJzBlPLoCzLm86oNBZBtLVg6mMRSvJ0djIRT2LxoX2oNGe3t16vljXl6wsJ5lq3KgFmIXBeCkDdT0tw8i7YGFdhWyrqoAVs06JN-_jFTGxHOBJqYU4g3II/s1600/22_Get+performance+statistics+for+cached+query.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="125" data-original-width="1600" height="50" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuABYgNcpAYA5kDXJPLyIHnXJzBlPLoCzLm86oNBZBtLVg6mMRSvJ0djIRT2LxoX2oNGe3t16vljXl6wsJ5lq3KgFmIXBeCkDdT0tw8i7YGFdhWyrqoAVs06JN-_jFTGxHOBJqYU4g3II/s640/22_Get+performance+statistics+for+cached+query.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
07.&amp;nbsp;Get execution plan for cached query: Execution Count, Plan Recompile, ParameterList, Query Plan, etc.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: sql"&gt;-- Get execution plan for cached query: Execution Count, Plan Recompile, ParameterList, Query Plan, etc.
SELECT TOP 10 st.text [TSQL], DB_NAME(st.dbid) [DB], 
 cp.usecounts [ExecutionCount], cp.size_in_bytes/1024.0 [PlanSize(KB)],
 cp.cacheobjtype [CacheObject], cp.objtype [ObjType], qs.plan_generation_num [PlanRecompile],
 qp.query_plan.query('declare namespace ns="http://schemas.microsoft.com/sqlserver/2004/07/showplan";
 (/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/ns:QueryPlan/ns:ParameterList/ns:ColumnReference[@Column])') [ParameterList], 
 qp.query_plan [QueryPlan], cp.plan_handle, qs.last_execution_time, qs.creation_time
FROM sys.dm_exec_cached_plans cp INNER JOIN sys.dm_exec_query_stats qs
         ON cp.plan_handle = qs.plan_handle
 CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) st
 CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) qp
WHERE st.dbid = DB_ID('AdventureWorks2014')
-- CHARINDEX ('Products', st.text) &amp;gt;0
-- st.text LIKE '%xxx%'
ORDER BY [ExecutionCount] DESC;
GO
&lt;/pre&gt;
&lt;br /&gt;
-- figure&amp;nbsp;31_Get execution plan for cached query&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEvk5QNuMhnFs-5Ot505XWPJte6Nsknfs5bSTE-hDPcqb57QqHqVowzh1xWdVy6DD5Yn2_NoEOnvhFItZyF_DpwXAd5oeLW5Ba1lDk0QMCb2ScpwENlcPE2xU73xLLnVSf76IHmnD_4IA/s1600/31_Get+execution+plan+for+cached+query.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="414" data-original-width="1600" height="164" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEvk5QNuMhnFs-5Ot505XWPJte6Nsknfs5bSTE-hDPcqb57QqHqVowzh1xWdVy6DD5Yn2_NoEOnvhFItZyF_DpwXAd5oeLW5Ba1lDk0QMCb2ScpwENlcPE2xU73xLLnVSf76IHmnD_4IA/s640/31_Get+execution+plan+for+cached+query.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
08. 檢視 回傳的結果：&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;32_Get execution plan for cached query_ParameterList&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwsQmrPH_cRRfsWot9-CF3a8ZK1qFM44t1sVIan33bwFSSChQ6eRKNOmuy5Nrd6OYMZHAb1U3DhpK6zDZVgeFnRJMS5dLjKPSjpavbiHX-eInmCyw3MIFxEB8cYzNJO9rSvMTGmoRd4uM/s1600/32_Get+execution+plan+for+cached+query_ParameterList.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="114" data-original-width="1202" height="60" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwsQmrPH_cRRfsWot9-CF3a8ZK1qFM44t1sVIan33bwFSSChQ6eRKNOmuy5Nrd6OYMZHAb1U3DhpK6zDZVgeFnRJMS5dLjKPSjpavbiHX-eInmCyw3MIFxEB8cYzNJO9rSvMTGmoRd4uM/s640/32_Get+execution+plan+for+cached+query_ParameterList.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
09.&amp;nbsp;-- Get execution plan for cached query: Execution Count, Plan Recompile, ParameterList, Query Plan, CompileTime, CompileMemory, SubTreeCost, etc.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: sql"&gt;-- Get execution plan for cached query: Execution Count, Plan Recompile, ParameterList, Query Plan, CompileTime, CompileMemory, SubTreeCost, etc.
WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' as ns)

SELECT TOP 10 st.text [TSQL], DB_NAME(st.dbid) [DB], 
 TRY_CAST(qp.query_plan.value('(/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/@StatementSubTreeCost)[1]', 'float') 
 AS decimal(38,7)) [StatementSubTreeCost],
 qp.query_plan.value('(/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/ns:QueryPlan/@CompileTime)[1]', 'int') [CompileTime(ms)], 
 qp.query_plan.value('(/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/ns:QueryPlan/@CompileCPU)[1]', 'int') [CompileCPU(ms)],
 qp.query_plan.value('(/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/ns:QueryPlan/@CompileMemory)[1]', 'int') [CompileMemory(KB)],
 qp.query_plan.value('(/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/@RetrievedFromCache)[1]', 'nvarchar(50)') [RetrievedFromCache],
 cp.usecounts [ExecutionCount], cp.size_in_bytes/1024.0 [PlanSize(KB)],
 cp.cacheobjtype [CacheObject], cp.objtype [ObjType], qs.plan_generation_num [PlanRecompile],
 qp.query_plan.query('(/ns:ShowPlanXML/ns:BatchSequence/ns:Batch/ns:Statements/ns:StmtSimple/ns:QueryPlan/ns:ParameterList/ns:ColumnReference[@Column])') [ParameterList],
 qp.query_plan [QueryPlan], cp.plan_handle, qs.last_execution_time, qs.creation_time
FROM sys.dm_exec_cached_plans cp INNER JOIN sys.dm_exec_query_stats qs
         ON cp.plan_handle = qs.plan_handle
 CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) st
 CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) qp
WHERE st.dbid = DB_ID('AdventureWorks2014') 
-- AND cp.objtype = 'Proc' CHARINDEX ('Products', st.text) &amp;gt;0
-- st.text LIKE '%xxx%'
ORDER BY StatementSubTreeCost DESC;
GO
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;41_Get execution plan for cached query&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEdeYM7-usOQ2MrdKLUS2Y7ZIoZ1xsBP8ogfq0oFASNesVUL60tSJUx3f08gVMlhvxIja0vQmQSdk6327GlIikqYyNPdOpaRcWSfPvZ_-ypUVJocBxR9fHd5gU29DmMihOccCo6L4N8HM/s1600/41_Get+execution+plan+for+cached+query.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="554" data-original-width="1600" height="220" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEdeYM7-usOQ2MrdKLUS2Y7ZIoZ1xsBP8ogfq0oFASNesVUL60tSJUx3f08gVMlhvxIja0vQmQSdk6327GlIikqYyNPdOpaRcWSfPvZ_-ypUVJocBxR9fHd5gU29DmMihOccCo6L4N8HM/s640/41_Get+execution+plan+for+cached+query.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;42_Get execution plan for cached query_ParameterList&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdVov1bYawlGxbuS5x8kxx40sIov8sCN1gq7DOnInRE2-lJIzC3PioSu1BC5pQEfuyL71j5y0nLVuQ0mt-ymBKOMgl9Yno-i2XlUBF52OfRE4gfgQ2Bgj9pRk3W8DrpAO5panpt6M05X8/s1600/42_Get+execution+plan+for+cached+query_ParameterList.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="136" data-original-width="990" height="86" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdVov1bYawlGxbuS5x8kxx40sIov8sCN1gq7DOnInRE2-lJIzC3PioSu1BC5pQEfuyL71j5y0nLVuQ0mt-ymBKOMgl9Yno-i2XlUBF52OfRE4gfgQ2Bgj9pRk3W8DrpAO5panpt6M05X8/s640/42_Get+execution+plan+for+cached+query_ParameterList.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Sample Code&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
20180730_Look at parameter_TSQL&lt;br /&gt;
&lt;a href="https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing"&gt;https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Reference&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
[SQL Server] SSMS: Look at parameter from execution plan, 查看 執行計畫 所使用的參數&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2017/12/sql-server-look-at-parameter-from.html"&gt;http://sharedderrick.blogspot.com/2017/12/sql-server-look-at-parameter-from.html&lt;/a&gt;</description><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQZqUkS97vsEuNtEPYKkuPVf9mqoDw06CJOlUlX9xaO7ftyiNr4sJdVnrleRiZbZiS_T6YNRcPuawtRWf2smGRKjsbjHvAqskY2kauZ16FQEdP429qqOMUKQK9waGAy86FaPD5P010UNs/s72-c/02_XML_ParameterList.png" width="72"/><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><title>[Performance Tuning] Parallel INSERT … SELECT with TABLOCK hint</title><link>http://sharedderrick.blogspot.com/2018/07/performance-tuning-parallel-insert.html</link><author>noreply@blogger.com (DerrickLaLa)</author><pubDate>Tue, 24 Jul 2018 07:50:00 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1420955872914622499.post-3052172309693185069</guid><description>&lt;br /&gt;
&lt;br /&gt;
SQL Server 2016 新增加 INSERT … SELECT with &lt;span style="color: blue;"&gt;TABLOCK&lt;/span&gt; hint，支援 Parallel 平行處理來提升效能。&lt;br /&gt;
&lt;br /&gt;
先前版本，雖然 TABLOCK，採取減少 Log 量 與 Lock 方式來提升效能。 但在 SQL Server 2016 再強化為 支援 Parallel 平行處理來優化效能。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
基本規則是&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;資料表沒有 Clustered Index，也就是 Heap(堆積)。&lt;/li&gt;
&lt;li&gt;資料庫的 COMPATIBILITY_LEVEL (相容性) = 130 含以上。&lt;/li&gt;
&lt;li&gt;INSERT ... SELECT 使用 TABLCOK。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
Parallel INSERT … SELECT with TABLOCK hint&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Table Without Clustered Index.&lt;/li&gt;
&lt;li&gt;The database compatibility level must be 130 and above.&lt;/li&gt;
&lt;li&gt;Must use the TABLOCK hint with the INSERT … SELECT statement.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiG0aSIkQ2ve2mViaZgXTB5dxgrdsyPCPJERsXl7XkFmIHPbBh7WHd5USylXwqoDq-DRZORh8BaYV_2iMF_v3q-I1q8a4xHvo9ccILqMQt0UrAjtj5VH-SjZVbXH-rWS-xNlKa7b5-RY9M/s1600/16_Table_Insert.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="521" data-original-width="846" height="394" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiG0aSIkQ2ve2mViaZgXTB5dxgrdsyPCPJERsXl7XkFmIHPbBh7WHd5USylXwqoDq-DRZORh8BaYV_2iMF_v3q-I1q8a4xHvo9ccILqMQt0UrAjtj5VH-SjZVbXH-rWS-xNlKa7b5-RY9M/s640/16_Table_Insert.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
使用 TABLOCK，效能提升：&lt;span style="color: blue;"&gt;71.5%&lt;/span&gt;&amp;nbsp;。&lt;br /&gt;
&lt;div&gt;
(0.061514000-0.105527000)/0.061514000 = 71.5%&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;table border="1" cellpadding="1" cellspacing="1"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;TSQL&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;LastElapsedTime(sec)&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#th1：&lt;span style="color: blue;"&gt;with TABLOCK&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="color: blue;"&gt;0.061514000&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#th2：without TABLOCK&lt;/td&gt;&lt;td&gt;0.105527000&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;#th3_ClusteredIndex：with TABLOCK, and with&amp;nbsp;&lt;span style="color: red;"&gt;Clustered Index&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="color: red;"&gt;0.123723000&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;[Performance Tuning] Parallel INSERT … SELECT with TABLOCK hint&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
01. 建立 temporary table (暫存資料表)。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;#th1 : 沒有 Clustered Index，也就是 Heap (堆積)。&lt;/li&gt;
&lt;li&gt;#th2 : 沒有 Clustered Index，也就是 Heap (堆積)。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;01_Create Table_without_Clustered Index&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIsvOUM5QXwnSpxnwRE1QJvZTJmKLDckIlOd1KPh0BXNNmSqPvLMVI_SwsOV_dvsyU1C5nKLqXoBhQAsE0o9sn9wvhBmdTFA0w1F-OrRK35klwcpESlLNNSGn8hBpz6X8UPzSFff5eErw/s1600/01_Create+Table_without_Clustered+Index.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="619" data-original-width="559" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIsvOUM5QXwnSpxnwRE1QJvZTJmKLDckIlOd1KPh0BXNNmSqPvLMVI_SwsOV_dvsyU1C5nKLqXoBhQAsE0o9sn9wvhBmdTFA0w1F-OrRK35klwcpESlLNNSGn8hBpz6X8UPzSFff5eErw/s640/01_Create+Table_without_Clustered+Index.png" width="576" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 建立 temporary table (暫存資料表)。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;#th3_ClusteredIndex : 有 Clustered Index。&lt;/li&gt;
&lt;li&gt;TransactionID 資料行，設定為 Clustered Index，也是 Primary Key。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;02_Create Table With Clustered Index&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiD5dbhgXJMxtQc9XtpJHb_AOG9VzcrzWCeStFzX1H-1UHmHZIHktK3PTMlxMpXmZgk-8vv1VV-D_xLfMmtyZgYSFHFC32EkcnjxCERiMKVfV4j20kQX5N_z76z54-_RaY7RLKwrwVI6LQ/s1600/02_Create+Table+With+Clustered+Index.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="315" data-original-width="557" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiD5dbhgXJMxtQc9XtpJHb_AOG9VzcrzWCeStFzX1H-1UHmHZIHktK3PTMlxMpXmZgk-8vv1VV-D_xLfMmtyZgYSFHFC32EkcnjxCERiMKVfV4j20kQX5N_z76z54-_RaY7RLKwrwVI6LQ/s640/02_Create+Table+With+Clustered+Index.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 新增資料列，使用 INSERT ... SELECT&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;#th1 : &lt;span style="color: blue;"&gt;INSERT ... SELECT &lt;/span&gt;，並加上使用 &lt;span style="color: blue;"&gt;&lt;b&gt;TABLOCK &lt;/b&gt;&lt;/span&gt;。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;Parallel Insert，&lt;span style="color: blue;"&gt;&lt;b&gt;平行處理&lt;/b&gt;&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;#th2 : 僅使用 INSERT ... SELECT 。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;無法 Parallel Inert，無法平行處理。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;11_WITH (TABLOCK)&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2e9D5gBEXS5PvfFN6D642WkrqnIFHGhasKhlcLkjad4n2xHE0p4lyrsTBEYYZShHFrX-KpyQ636PMJu0P0CM2FoKevLQP0iIB_WTJSuM-MMWI_jH88WDoH3uFR1SOj77OZxTTCtudkMY/s1600/11_WITH+%2528TABLOCK%2529.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="191" data-original-width="582" height="210" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2e9D5gBEXS5PvfFN6D642WkrqnIFHGhasKhlcLkjad4n2xHE0p4lyrsTBEYYZShHFrX-KpyQ636PMJu0P0CM2FoKevLQP0iIB_WTJSuM-MMWI_jH88WDoH3uFR1SOj77OZxTTCtudkMY/s640/11_WITH+%2528TABLOCK%2529.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
04. 觀察 Execution Plan，兩相比較下&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;有使用 TABLOCK hint，僅占 36% 成本資源。&lt;/li&gt;
&lt;li&gt;觀察到有 Parallelism 平行處理的 圖示。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;12_Execution_Plan&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyy7NIrVys8VrzoPfeLKdGnsFZ8MVKwCQ6R-uLZQul-qe3Zi8gj2sMwo10u3K6bM8uAmy7N9YZi9nPyAJNvsHohNqs0NMsO-LLDhGnxkFXlh9Zb9ztNnoO1SLHixdS0nIu5ixx00wSD6Y/s1600/12_Execution_Plan.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="340" data-original-width="985" height="220" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyy7NIrVys8VrzoPfeLKdGnsFZ8MVKwCQ6R-uLZQul-qe3Zi8gj2sMwo10u3K6bM8uAmy7N9YZi9nPyAJNvsHohNqs0NMsO-LLDhGnxkFXlh9Zb9ztNnoO1SLHixdS0nIu5ixx00wSD6Y/s640/12_Execution_Plan.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
05. 使用 Plan Explorer 來做觀察：&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;有使用 TABLOCK&lt;/span&gt;，Cost 僅使用 &lt;span style="color: blue;"&gt;36%&lt;/span&gt;，Parallel Operations 是 &lt;span style="color: blue;"&gt;4&lt;/span&gt; 。&lt;/li&gt;
&lt;li&gt;沒用 TABLOCK，Cost 多耗用至 &lt;span style="color: red;"&gt;63.8%&lt;/span&gt;，Parallel Operations 是 &lt;span style="color: red;"&gt;1 &lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;13_Execution_Plan_Plan_Explorer&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjQRkPZLVVpPjVW_JV3ZdHdtE9EpLaKq1PV44m8As_p8AKfqWqaFxtsLk3Feex6LjYglAMAjnCF7F3Av1BTqvsiiva2GKzRN1zo2KUN_ObgfQnNY3x5ATUtPyuwL3R-7i__IBNgb-mA/s1600/13_Execution_Plan_Plan_Explorer.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="102" data-original-width="1063" height="60" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjQRkPZLVVpPjVW_JV3ZdHdtE9EpLaKq1PV44m8As_p8AKfqWqaFxtsLk3Feex6LjYglAMAjnCF7F3Av1BTqvsiiva2GKzRN1zo2KUN_ObgfQnNY3x5ATUtPyuwL3R-7i__IBNgb-mA/s640/13_Execution_Plan_Plan_Explorer.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
06. 進一步觀察 Execution Plan:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;有使用 TABLOCK&lt;/span&gt;，Subtree Cost 是: &lt;span style="color: blue;"&gt;3.34141&lt;/span&gt;。&lt;/li&gt;
&lt;li&gt;沒用 TABLOCK，Subtree Cost 高達: &lt;span style="color: red;"&gt;5.89468&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;14&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1rcbmnaYdTRKnGEu5YyrWT_G1fpQThGYc1eexfUow6rDOoJmcHiJG1ay_wFX0m322BI0TU4B2oaZNtatgiBHkHLOuW96og8VVrEl1UfjEMDV5Svu8o1uEcBuIvLA9hC5wlfUhLV7cZAU/s1600/14.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="385" data-original-width="976" height="252" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1rcbmnaYdTRKnGEu5YyrWT_G1fpQThGYc1eexfUow6rDOoJmcHiJG1ay_wFX0m322BI0TU4B2oaZNtatgiBHkHLOuW96og8VVrEl1UfjEMDV5Svu8o1uEcBuIvLA9hC5wlfUhLV7cZAU/s640/14.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
-- figure&amp;nbsp;15&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1umY6B45Sm3eDcxhEwyoHLJvRmBAzNQPXrmPXdrOB4QLLBbbzQMaOxNrfxWWpduvBOpbObopZpQc8VYuSJZRBH4UuvWsDvLiOjgItJPBhzKinyyvoUP2Bf5TW_Pj8d2o15lkUGpmPDh8/s1600/15.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="447" data-original-width="985" height="290" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1umY6B45Sm3eDcxhEwyoHLJvRmBAzNQPXrmPXdrOB4QLLBbbzQMaOxNrfxWWpduvBOpbObopZpQc8VYuSJZRBH4UuvWsDvLiOjgItJPBhzKinyyvoUP2Bf5TW_Pj8d2o15lkUGpmPDh8/s640/15.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
07. 觀察 Table Insert operator:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;有使用 TABLOCK，可以 Parallel 平行處理。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;留意：&lt;b&gt;&lt;span style="color: blue;"&gt;Number of Executions&lt;/span&gt;&lt;/b&gt; 是：&lt;span style="color: blue;"&gt;&lt;b&gt;4&lt;/b&gt;&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;沒有 TABLOCK，&lt;span style="color: red;"&gt;不&lt;/span&gt;支援 Parallel 平行處理。&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;留意：Number of Executions 是：&lt;span style="color: red;"&gt;1&lt;/span&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;16_Table_Insert&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4WoH6ZVyQtgMkCTZkVrAM_hyphenhyphennr8cMW7AenfVNISXNcOTLJQo8ECVO2oKJtiyPTH_S_mlXZOiYNBNoSEABhN4KUvBsQuEp3NcMLw1qgu6moow7Z42R-VT5R_YIn1EvBI6ftzFdjbM0U28/s1600/16_Table_Insert.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="521" data-original-width="846" height="394" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4WoH6ZVyQtgMkCTZkVrAM_hyphenhyphennr8cMW7AenfVNISXNcOTLJQo8ECVO2oKJtiyPTH_S_mlXZOiYNBNoSEABhN4KUvBsQuEp3NcMLw1qgu6moow7Z42R-VT5R_YIn1EvBI6ftzFdjbM0U28/s640/16_Table_Insert.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;17_Table_Insert&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOZp8NqUXEID6nxjP7Co6-VV7UL2V-DxL36B25WXWTgdDrxGp7Lj3T_S3preoA7Q-kIDu547g3P5yKt86Sgtd3EBNXoW4VrwNaVGKjDfmV9yyrDx1C43zoEHcsTOrwHjyWTgiTVEGgB_w/s1600/17_Table_Insert.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="523" data-original-width="842" height="396" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOZp8NqUXEID6nxjP7Co6-VV7UL2V-DxL36B25WXWTgdDrxGp7Lj3T_S3preoA7Q-kIDu547g3P5yKt86Sgtd3EBNXoW4VrwNaVGKjDfmV9yyrDx1C43zoEHcsTOrwHjyWTgiTVEGgB_w/s640/17_Table_Insert.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
08. 觀察 Performance Data：&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;使用 TABLOCK，效能提升：&lt;span style="color: blue;"&gt;71.5%&lt;/span&gt; 。&lt;/li&gt;
&lt;li&gt;Improvement = (Original_Response_Time - Improved_Response_Time) / Original_Response_Time * 100%&lt;/li&gt;
&lt;li&gt;(0.061514000-0.105527000)/0.061514000 = 71.5%&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;table border="1" cellpadding="1" cellspacing="1"&gt;
 &lt;tbody&gt;
&lt;tr&gt;
   &lt;td&gt;&lt;b&gt;TSQL&lt;/b&gt;&lt;/td&gt;
   &lt;td&gt;&lt;b&gt;LastElapsedTime(sec)&lt;/b&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt;
   &lt;td&gt;#th1：&lt;span style="color: blue;"&gt;with TABLOCK&lt;/span&gt;&lt;/td&gt;
   &lt;td&gt;&lt;span style="color: blue;"&gt;0.061514000&lt;/span&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt;
   &lt;td&gt;#th2：without TABLOCK&lt;/td&gt;
   &lt;td&gt;0.105527000&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt;
   &lt;td&gt;#th3_ClusteredIndex：with TABLOCK, and with &lt;span style="color: red;"&gt;Clustered Index&lt;/span&gt;&lt;/td&gt;
   &lt;td&gt;&lt;span style="color: red;"&gt;0.123723000&lt;/span&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;18_Performance_Data&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjndUDbXQHKAUkcQvFWQRrWZtWcKHlz-8bEIwiUf0XYLjrUgiYKyMiZKdEoEz7a-SlEs-O_YOEKtyByf8ntQt0XTuggI0JRt8fc8l5D8A750PjeZ2xERbPG9xK8ayjSXZLTkLO8sW9IKMs/s1600/18_Performance_Data.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="101" data-original-width="1397" height="46" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjndUDbXQHKAUkcQvFWQRrWZtWcKHlz-8bEIwiUf0XYLjrUgiYKyMiZKdEoEz7a-SlEs-O_YOEKtyByf8ntQt0XTuggI0JRt8fc8l5D8A750PjeZ2xERbPG9xK8ayjSXZLTkLO8sW9IKMs/s640/18_Performance_Data.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
09. 比較以下 INSERT ... SELECT ：&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;#th1：with TABLOCK&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;可 平行處理。Parallel Insert&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;#th2：without TABLOCK&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;無法 平行處理。Not Parallel&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;#th3_ClusteredIndex：with TABLOCK, and with Clustered Index&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;無法 平行處理。Not Parallel&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;19_Different type of INSERT ... SELECT&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjI60U1kL9rR9VIAsg_3SLXDB8LXU8b3AbFkNIfp6xap-0jIhFWz_iGv1jJZaprYsbLPyiHjjeozpqFoBrFcW3CRAjAjNwoJNRPJKUfJmwFmw6uNoJWh85YTbCI_vaorb0PsOIJUY1g0Kk/s1600/19_.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="386" data-original-width="593" height="416" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjI60U1kL9rR9VIAsg_3SLXDB8LXU8b3AbFkNIfp6xap-0jIhFWz_iGv1jJZaprYsbLPyiHjjeozpqFoBrFcW3CRAjAjNwoJNRPJKUfJmwFmw6uNoJWh85YTbCI_vaorb0PsOIJUY1g0Kk/s640/19_.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
10. 觀察 Execution Plan&lt;br /&gt;
&lt;br /&gt;
-- figure 20_Compare_3&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKNLmAbCcJH0jWWGA8G41k-IRhOnXJVJ3SZVxPQ-VydWp0ClV667R_H8f2q48BbwtxrO6aH3mDlyqcT5_Qq5di5E0Mbexr_S_EZa3o4PbWRsPZyo-IMeotonLhqgKFGmE2bBGtUxV7n9c/s1600/19_Compare_3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="417" data-original-width="1219" height="218" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKNLmAbCcJH0jWWGA8G41k-IRhOnXJVJ3SZVxPQ-VydWp0ClV667R_H8f2q48BbwtxrO6aH3mDlyqcT5_Qq5di5E0Mbexr_S_EZa3o4PbWRsPZyo-IMeotonLhqgKFGmE2bBGtUxV7n9c/s640/19_Compare_3.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;The database compatibility level must be 130 and above.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
01. 調降 database compatibility level 為 120。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;21_database compatibility level&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioBpmWJl6qG9C5Cv1vckHH6r3eK-fxhuti3uNZ71BeJ8JYJVF_Sz-oQDImzyh578jQ4ZiRg9Cr82RgL1m0JzSDMolWrK-N41a67yMxmRAS4KhyphenhyphenhzbLn22oeDDZe-QdMOiuwQUcs85GHpY/s1600/21_database+compatibility+level.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="283" data-original-width="751" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioBpmWJl6qG9C5Cv1vckHH6r3eK-fxhuti3uNZ71BeJ8JYJVF_Sz-oQDImzyh578jQ4ZiRg9Cr82RgL1m0JzSDMolWrK-N41a67yMxmRAS4KhyphenhyphenhzbLn22oeDDZe-QdMOiuwQUcs85GHpY/s640/21_database+compatibility+level.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 確認該資料庫是 降級使用&amp;nbsp;COMPATIBILITY_LEVEL = 120&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;22_COMPATIBILITY_LEVEL = 120&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4ARvInBWWzrmgDwL7_77V7v3Bqecdaf5ZIL7RH-rAwJJvVoT-YzWjaL4cxyKMMImL8khf6G96vY7cJKTDaDYAvHEXh9j9n6P7uKTb-j-4a8hPb6pgoW8XCjjmOlI402yKRRRLHHguaDo/s1600/22_COMPATIBILITY_LEVEL+%253D+120.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="222" data-original-width="286" height="496" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4ARvInBWWzrmgDwL7_77V7v3Bqecdaf5ZIL7RH-rAwJJvVoT-YzWjaL4cxyKMMImL8khf6G96vY7cJKTDaDYAvHEXh9j9n6P7uKTb-j-4a8hPb6pgoW8XCjjmOlI402yKRRRLHHguaDo/s640/22_COMPATIBILITY_LEVEL+%253D+120.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 再度執行 INSERT ... SELECT&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;23_INSERT_SELECT&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFD8AumKyZlO1GC_ugWcRiQR5vcKDpM5DT_LHRWTWOxE9Q2kxj5Hz74nAzTXHvSvuU6LeGIHbxO0vcuFmskpTAzIM5AjAqtkGQo_EdYI33sMGTwl85isibv8LoK3b1GAdtrhYUQBAQFdE/s1600/23_INSERT_SELECT.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="314" data-original-width="598" height="336" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFD8AumKyZlO1GC_ugWcRiQR5vcKDpM5DT_LHRWTWOxE9Q2kxj5Hz74nAzTXHvSvuU6LeGIHbxO0vcuFmskpTAzIM5AjAqtkGQo_EdYI33sMGTwl85isibv8LoK3b1GAdtrhYUQBAQFdE/s640/23_INSERT_SELECT.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
04. 觀察 Execution Plan:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;都不支援 平行處理。&lt;/li&gt;
&lt;li&gt;Non-Parallel execution in all script.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
這是由於 COMPATIBILITY_LEVEL 必須要在 130 以上才支援 平行處理。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;24_Execution_Plan&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3XT_whhAeoekRCX9_pwUSZyVw8JwOZjmTkNPBvMeqQC1ocDw_mt1KSGnsubgnko8XMjEHIlV4ktCkMwW26LEF5F13wy2tEFs_IdC78uJ-hg5nUkMF287JzsbEb3f-8ajXTp_dfAuPW2c/s1600/24_Execution_Plan.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="395" data-original-width="1117" height="226" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3XT_whhAeoekRCX9_pwUSZyVw8JwOZjmTkNPBvMeqQC1ocDw_mt1KSGnsubgnko8XMjEHIlV4ktCkMwW26LEF5F13wy2tEFs_IdC78uJ-hg5nUkMF287JzsbEb3f-8ajXTp_dfAuPW2c/s640/24_Execution_Plan.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;大量匯入資料的最佳做法&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
使用 INSERT INTO…SELECT 搭配最低限度記錄來大量匯入資料&lt;br /&gt;
您可以搭配使用 INSERT INTO &lt;target_table&gt; SELECT &lt;columns&gt; FROM &lt;source_table&gt; 最低限度記錄，&lt;/source_table&gt;&lt;/columns&gt;&lt;/target_table&gt;&lt;br /&gt;
&lt;br /&gt;
有效率地將大量資料列從某份資料表 (例如暫存表格) 傳送至另一份資料表。&lt;br /&gt;
&lt;br /&gt;
最低限度記錄可以改善此陳述式的效能並且降低交易期間作業填滿可用交易記錄空間的可能性。&lt;br /&gt;
&lt;br /&gt;
此陳述式的最低限度記錄具有下列需求：&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;資料庫的復原模式設為&amp;nbsp;&lt;span style="background-color: white; font-family: &amp;quot;segoe ui&amp;quot; , &amp;quot;segoeui&amp;quot; , &amp;quot;segoe wp&amp;quot; , &amp;quot;helvetica neue&amp;quot; , &amp;quot;helvetica&amp;quot; , &amp;quot;tahoma&amp;quot; , &amp;quot;arial&amp;quot; , sans-serif; font-size: 16px;"&gt;simple&amp;nbsp;(&lt;/span&gt;簡單) 或&amp;nbsp;&lt;span style="background-color: white; font-family: &amp;quot;segoe ui&amp;quot; , &amp;quot;segoeui&amp;quot; , &amp;quot;segoe wp&amp;quot; , &amp;quot;helvetica neue&amp;quot; , &amp;quot;helvetica&amp;quot; , &amp;quot;tahoma&amp;quot; , &amp;quot;arial&amp;quot; , sans-serif; font-size: 16px;"&gt;bulk-logged(&lt;/span&gt;大量記錄)。&lt;/li&gt;
&lt;li&gt;目標資料表是空白或非空白的&amp;nbsp;&lt;span style="background-color: white; font-family: &amp;quot;segoe ui&amp;quot; , &amp;quot;segoeui&amp;quot; , &amp;quot;segoe wp&amp;quot; , &amp;quot;helvetica neue&amp;quot; , &amp;quot;helvetica&amp;quot; , &amp;quot;tahoma&amp;quot; , &amp;quot;arial&amp;quot; , sans-serif; font-size: 16px;"&gt;heap(&lt;/span&gt;堆積)。&lt;/li&gt;
&lt;li&gt;目標資料表未用於 複寫。&lt;/li&gt;
&lt;li&gt;針對目標資料表指定了 TABLOCK 提示。&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;br /&gt;
由於 MERGE 陳述式中的插入動作而插入堆積的資料列也可以採用最低限度記錄。&lt;br /&gt;
&lt;br /&gt;
與 BULK INSERT 陳述式 (持有較不嚴格的大量更新鎖定) 不同之處在於，&lt;br /&gt;
具 TABLOCK 提示的 INSERT INTO…SELECT 對資料表持有獨佔 (X) 鎖定。&lt;br /&gt;
這代表您無法使用平行插入作業插入資料列。&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Sample Code&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
20180724_INSERT_SELECT_TABLOCK&lt;br /&gt;
&lt;a href="https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing"&gt;https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Reference&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
SQLSweet16!, Episode 3: Parallel INSERT … SELECT&lt;br /&gt;
&lt;a href="https://blogs.msdn.microsoft.com/sqlcat/2016/07/06/sqlsweet16-episode-3-parallel-insert-select/"&gt;https://blogs.msdn.microsoft.com/sqlcat/2016/07/06/sqlsweet16-episode-3-parallel-insert-select/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Real World Parallel INSERT…SELECT: What else you need to know!&lt;br /&gt;
&lt;a href="https://blogs.msdn.microsoft.com/sqlcat/2016/07/21/real-world-parallel-insert-what-else-you-need-to-know/"&gt;https://blogs.msdn.microsoft.com/sqlcat/2016/07/21/real-world-parallel-insert-what-else-you-need-to-know/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Columnstore Index: Parallel load into clustered columnstore index from staging table&lt;br /&gt;
&lt;a href="https://blogs.msdn.microsoft.com/sqlserverstorageengine/2016/07/19/columnstore-index-parallel-load-into-clustered-columnstore-index-from-staging-table/"&gt;https://blogs.msdn.microsoft.com/sqlserverstorageengine/2016/07/19/columnstore-index-parallel-load-into-clustered-columnstore-index-from-staging-table/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
The Data Loading Performance Guide&lt;br /&gt;
&lt;a href="https://docs.microsoft.com/zh-tw/previous-versions/sql/sql-server-2008/dd425070(v=sql.100)"&gt;https://docs.microsoft.com/zh-tw/previous-versions/sql/sql-server-2008/dd425070(v=sql.100)&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Poor performance when you run INSERT.. SELECT operations in SQL Server 2016 or SQL Server 2017 on Windows&lt;br /&gt;
&lt;a href="https://support.microsoft.com/en-us/help/3180087/poor-performance-when-you-run-insert-select-operations-in-sql-server-2"&gt;https://support.microsoft.com/en-us/help/3180087/poor-performance-when-you-run-insert-select-operations-in-sql-server-2&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
INSERT (Transact-SQL)&lt;br /&gt;
&lt;a href="https://docs.microsoft.com/en-us/sql/t-sql/statements/insert-transact-sql?view=sql-server-2017"&gt;https://docs.microsoft.com/en-us/sql/t-sql/statements/insert-transact-sql?view=sql-server-2017&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
</description><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiG0aSIkQ2ve2mViaZgXTB5dxgrdsyPCPJERsXl7XkFmIHPbBh7WHd5USylXwqoDq-DRZORh8BaYV_2iMF_v3q-I1q8a4xHvo9ccILqMQt0UrAjtj5VH-SjZVbXH-rWS-xNlKa7b5-RY9M/s72-c/16_Table_Insert.png" width="72"/><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><title>[SSMS] Dark Theme</title><link>http://sharedderrick.blogspot.com/2018/07/ssms-selecting-dark-theme.html</link><category>SQL Server</category><author>noreply@blogger.com (DerrickLaLa)</author><pubDate>Fri, 20 Jul 2018 22:10:00 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1420955872914622499.post-318318352463326580</guid><description>&lt;br /&gt;
目前，SSMS 17.x 提供 2 種 theme。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Blue&lt;/li&gt;
&lt;li&gt;Light&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
若想要&amp;nbsp;&lt;b&gt;&lt;span style="font-size: large;"&gt;Dark &lt;/span&gt;&lt;/b&gt;theme，則需要 額外編輯 ssms.pkgundef。&lt;br /&gt;
&lt;br /&gt;
雖然還未得到 Microsoft 正式支援，但確實可讓 SSMS 切換為 Dark theme 。&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIpcrQBP4YViq70m0EnX6jsAd0pGe5J2p7aBo4aG7sALgIc6p7WWP5GByxP5k6Mtnbb2uSKxzunaHi-Ei6rLeWcO4uSm1agnlOLCgHR433qPV_6_xt0mWioDvu9bi_wlfjPn3bVjfWans/s1600/31_SSMS.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="806" data-original-width="1314" height="392" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIpcrQBP4YViq70m0EnX6jsAd0pGe5J2p7aBo4aG7sALgIc6p7WWP5GByxP5k6Mtnbb2uSKxzunaHi-Ei6rLeWcO4uSm1agnlOLCgHR433qPV_6_xt0mWioDvu9bi_wlfjPn3bVjfWans/s640/31_SSMS.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;SSMS: Selecting the Dark Theme&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;版本: SSMS 17.x&lt;/li&gt;
&lt;li&gt;示範作業系統： Windows 10&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
00. 請先關閉 SSMS。&lt;br /&gt;
&lt;br /&gt;
01. 使用檔案總管，尋找與檢視 文字格式檔案：&amp;nbsp;&lt;b&gt;&lt;span style="color: blue;"&gt;ssms.pkgundef&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
SSMS 17.x 的存放路徑：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;C:\Program Files (x86)\Microsoft SQL Server\140\Tools\Binn\ManagementStudio&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;11_ssms.pkgundef&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2vEwlm38wKEXDy18cwaUALyzf6xIXbo3VD5jrZpMv7Wonp-0Fgsa4J2NoMlabA3AXheQvPdG_K4HLSmpfV8ZcVV7l1AMdycrJiRgkYN_k5mNWgth6m-vtsIZpW6ZMRVY-LnLNq6Iffms/s1600/11_ssms.pkgundef.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="326" data-original-width="836" height="248" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2vEwlm38wKEXDy18cwaUALyzf6xIXbo3VD5jrZpMv7Wonp-0Fgsa4J2NoMlabA3AXheQvPdG_K4HLSmpfV8ZcVV7l1AMdycrJiRgkYN_k5mNWgth6m-vtsIZpW6ZMRVY-LnLNq6Iffms/s640/11_ssms.pkgundef.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 編輯此文字檔案:&amp;nbsp;ssms.pkgundef&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;尋找到關鍵字：&lt;b&gt;&lt;span style="color: blue;"&gt;// Remove Dark Theme&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;12_Remove Dark theme&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPfQPr3xJd5ZP0VOBswyQVjjah9e93gPP04Xi4fZCzWit_Ur3DSJPOpruVRTPEZzxTRA1X-6l9Vb-SMe8d2jR5L-wZ37nIr7N7CR5oz1TvIMjZt4mA2rerXKQutd5_isc_onKTiTvzbDQ/s1600/12_Remove+Dark+theme.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="577" data-original-width="810" height="454" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPfQPr3xJd5ZP0VOBswyQVjjah9e93gPP04Xi4fZCzWit_Ur3DSJPOpruVRTPEZzxTRA1X-6l9Vb-SMe8d2jR5L-wZ37nIr7N7CR5oz1TvIMjZt4mA2rerXKQutd5_isc_onKTiTvzbDQ/s640/12_Remove+Dark+theme.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 使用 &lt;b&gt;&lt;span style="color: blue;"&gt;//&lt;/span&gt;&lt;/b&gt; 註解，將&amp;nbsp;// Remove Dark Theme 下的第 &lt;span style="color: blue;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt; 行給註解掉。請參考下圖所示：&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;[$RootKey$\Themes\{1ded0138-47ce-435e-84ef-9ec1f439b749}]&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;13_comment out first line&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6KAW-JwXS4rXDC3Qq_B_ywFf89L6U19fTY-yxRnGrhbR_K2wfUZQpMXw8_WumZnYM4IHUQYx_7zfK0zEFRbKXM7tqpaZ5SAae_AEuDAPzvNbXUAwjEGCPpOcbCgkbMEyGerthjh2Uw1c/s1600/13_comment+out+first+line.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="599" data-original-width="819" height="468" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6KAW-JwXS4rXDC3Qq_B_ywFf89L6U19fTY-yxRnGrhbR_K2wfUZQpMXw8_WumZnYM4IHUQYx_7zfK0zEFRbKXM7tqpaZ5SAae_AEuDAPzvNbXUAwjEGCPpOcbCgkbMEyGerthjh2Uw1c/s640/13_comment+out+first+line.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
04. 儲存檔案&amp;nbsp;ssms.pkgundef&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;若不是使用 Administrator 管理者身分編輯時，將遭遇到以下錯誤訊息，請點選 Yes。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;41_Notepad_without_Administrator&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKo9Vs_Pheu8RdNg-fEkRuqU-VBxu1Pur7Gd0DeagveQYxP1Bw-JKgG0QxJ-ArOIlND5Hz7RCxO3IPnmUM720CC2kswEWxYc3rONFrgQ0-3CHKYLung4MtTiq6wUGYLewCI9V2nY1ddn8/s1600/41_Notepad_witout_Administrator.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="646" data-original-width="1152" height="358" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKo9Vs_Pheu8RdNg-fEkRuqU-VBxu1Pur7Gd0DeagveQYxP1Bw-JKgG0QxJ-ArOIlND5Hz7RCxO3IPnmUM720CC2kswEWxYc3rONFrgQ0-3CHKYLung4MtTiq6wUGYLewCI9V2nY1ddn8/s640/41_Notepad_witout_Administrator.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
05. 再點選 Yes，調整 UAC: User Account Control。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;42_Click_YES&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNkRt_-7y42c6BJWEa6g_oIMa38VUHG0t05ZqikRUJE4WPbqV1jSCgvE0zxlCScDjRbnTVYWjZLhyXSowVyT6yNa7lSaiCZ59VlnyQFLCGogSCOzt9_BWRm5a1UIivcc7g6u7MDPJN3jU/s1600/42_Click_YES.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="336" data-original-width="457" height="470" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNkRt_-7y42c6BJWEa6g_oIMa38VUHG0t05ZqikRUJE4WPbqV1jSCgvE0zxlCScDjRbnTVYWjZLhyXSowVyT6yNa7lSaiCZ59VlnyQFLCGogSCOzt9_BWRm5a1UIivcc7g6u7MDPJN3jU/s640/42_Click_YES.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
06. 確認儲存檔案：ssms.pkgundef。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
07. 開啟 SSMS&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;點選 Tools / Options。&lt;/li&gt;
&lt;li&gt;在左邊窗格，點選 Environment / General。&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;在右邊窗格，在 Color theme，下拉，可以看到 3 種 theme：&lt;b&gt;&lt;span style="color: blue;"&gt;Blue, Dark, Light&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;21_Select_Dark_theme&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5pqB2VmPAdPL-pdaEhpkOrOdyYUxaPdZ47_FAmRKk0NaGczcq7rDLn99GmqkOuCndi_sqpAtdXsSKkb50BTkgsX-tAamrGeH_QE814__Sio81UqP7MESInikQ6YPf_gQHL2eqwVc9Tjg/s1600/21_Select_Dark_theme.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="434" data-original-width="744" height="372" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5pqB2VmPAdPL-pdaEhpkOrOdyYUxaPdZ47_FAmRKk0NaGczcq7rDLn99GmqkOuCndi_sqpAtdXsSKkb50BTkgsX-tAamrGeH_QE814__Sio81UqP7MESInikQ6YPf_gQHL2eqwVc9Tjg/s640/21_Select_Dark_theme.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
08. 確認選擇：Dark theme。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;22_Dark&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBd6kY_aobOr3klHseSpZacgCLnJx8O5tCu4_vAZXAjsnRckrfcaGt_9lqdXoPj3PtEopqXxThqJ_EHmpSwSqgQPunEm54oYTWGYJnIAEFFMln54Yp35-QHF9AnzSH0kPE2YbcbRb-aqg/s1600/22_Dark.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="436" data-original-width="747" height="372" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBd6kY_aobOr3klHseSpZacgCLnJx8O5tCu4_vAZXAjsnRckrfcaGt_9lqdXoPj3PtEopqXxThqJ_EHmpSwSqgQPunEm54oYTWGYJnIAEFFMln54Yp35-QHF9AnzSH0kPE2YbcbRb-aqg/s640/22_Dark.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
若未正確設定，只能看到 2 種 theme：Blue, Light。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;29_Original&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1iLWXVPTUUijZeExM9VOjtDVkCnyiSpX8Os9NWPHXk80PzE9YzGCCbbhyphenhyphenPK6c4Cqgq81JLKIKcJ2kh8qycAkhVMLyK9bZyttDS5AwYzjOMenT2_6ZWq-SuzeYUKxY19lXmT83-f1qPHU/s1600/29_Original.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="442" data-original-width="750" height="376" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1iLWXVPTUUijZeExM9VOjtDVkCnyiSpX8Os9NWPHXk80PzE9YzGCCbbhyphenhyphenPK6c4Cqgq81JLKIKcJ2kh8qycAkhVMLyK9bZyttDS5AwYzjOMenT2_6ZWq-SuzeYUKxY19lXmT83-f1qPHU/s640/29_Original.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
09. 已經切換為 Dark theme&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;31_SSMS&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7-r0WZTKXSs1hN9jcnxVPiUeFRj_af0LIUBrHJ5QoioWfCcTI6Gay3RLBnW-blkZZtSmdK5XRSbGP9lsZge4-t111y_JtMZZHQfdbHfIbrnJfm9Dn6bycp1ZaHUuX-wHyU-Zcl6Phl3c/s1600/31_SSMS.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="806" data-original-width="1314" height="392" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7-r0WZTKXSs1hN9jcnxVPiUeFRj_af0LIUBrHJ5QoioWfCcTI6Gay3RLBnW-blkZZtSmdK5XRSbGP9lsZge4-t111y_JtMZZHQfdbHfIbrnJfm9Dn6bycp1ZaHUuX-wHyU-Zcl6Phl3c/s640/31_SSMS.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
10. 可惜，仍有部分視窗沒有 &lt;span style="font-size: large;"&gt;&lt;b&gt;黑化&lt;/b&gt;&lt;/span&gt;。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Results&lt;/li&gt;
&lt;li&gt;Messages&lt;/li&gt;
&lt;li&gt;Execution Plan&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;31_SSMS_Results&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikikoxBdrr3jFqdZSreUVv3TGbIPnPCSobqFkPmqoLGsBShnYUxMJu6xmkvlJwUwhMBn-SANjqeYEIoZNdYO0sLko5cwfGi2MBD5W0epaqeB4zmC_zpI5_7w293OWaeKlhjSxDBL4P2nE/s1600/31_SSMS_Results.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="806" data-original-width="1314" height="392" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikikoxBdrr3jFqdZSreUVv3TGbIPnPCSobqFkPmqoLGsBShnYUxMJu6xmkvlJwUwhMBn-SANjqeYEIoZNdYO0sLko5cwfGi2MBD5W0epaqeB4zmC_zpI5_7w293OWaeKlhjSxDBL4P2nE/s640/31_SSMS_Results.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
11. 視窗 Object Explorer 也未 黑化。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;32_SSMS_Object_Explorer&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLZNxvRfGwpU08knuLZZ2494rVMV_NNrcEIYJRpfNLEoTF2kIaFwON7dzlFvIKz4E6bawT-OMJPa6VYsB7q88Xq68UHBUFpmGDGBOmVSSoZbPxu1W5O9yVr-m_JzIIJgArRJLGg60YOZg/s1600/32_SSMS_Object_Explorer.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="806" data-original-width="1314" height="392" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLZNxvRfGwpU08knuLZZ2494rVMV_NNrcEIYJRpfNLEoTF2kIaFwON7dzlFvIKz4E6bawT-OMJPa6VYsB7q88Xq68UHBUFpmGDGBOmVSSoZbPxu1W5O9yVr-m_JzIIJgArRJLGg60YOZg/s640/32_SSMS_Object_Explorer.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
12. 視窗 Registered Servers 也尚未 黑化。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;33_SSMS_Registered_Servers&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4fujSqvM6zFqgcWKnoP1vtVQwLokfkyjp2SMFysaa9AQmA52-Y1iqH4hFPYPJvCOC8DKBCsYQFQi1gzFD-R-xOlgrYriCKI0A-v09as5-LVwdWkzrYD3alSr2ALwCT8Mo9hgJYMhrgY4/s1600/33_SSMS_Registered_Servers.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="806" data-original-width="1314" height="392" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4fujSqvM6zFqgcWKnoP1vtVQwLokfkyjp2SMFysaa9AQmA52-Y1iqH4hFPYPJvCOC8DKBCsYQFQi1gzFD-R-xOlgrYriCKI0A-v09as5-LVwdWkzrYD3alSr2ALwCT8Mo9hgJYMhrgY4/s640/33_SSMS_Registered_Servers.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
13. 切換為 &lt;b&gt;&lt;span style="color: blue;"&gt;Light theme&lt;/span&gt;&lt;/b&gt;。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;51_Light_theme&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiU2JnfsDXJID4M9hpqXoxAQ0Vp0_g1p6e40hMN8RBpCEhMy_mfeG1l1tnF6dcO319qYvwV3zMQszbUEXB_PiHR11cbpZ1NoXp3UWVciLgGOH1cObWB0UhpFXmK-TDaa-4zdzkWXFYajM8/s1600/51_Light_theme.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="751" data-original-width="1314" height="364" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiU2JnfsDXJID4M9hpqXoxAQ0Vp0_g1p6e40hMN8RBpCEhMy_mfeG1l1tnF6dcO319qYvwV3zMQszbUEXB_PiHR11cbpZ1NoXp3UWVciLgGOH1cObWB0UhpFXmK-TDaa-4zdzkWXFYajM8/s640/51_Light_theme.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
14. 切換為 預設 &lt;b&gt;&lt;span style="color: blue;"&gt;Blue theme&lt;/span&gt;&lt;/b&gt;。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;52_Blue_theme&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvJNNmbPEbbIQjO6RfVibaPkWtUV5gIRjp73M2QO5XCUYdm6_Vl2lwaXcQivwQERwQiwGMctT0F_nYYpBRGywiWKkcr-GiZzsQdXZMiAaNvHerMGItuDhSr2mlhEqhy8j3qBrWdt6xLcI/s1600/52_Blue_theme.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="751" data-original-width="1314" height="364" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvJNNmbPEbbIQjO6RfVibaPkWtUV5gIRjp73M2QO5XCUYdm6_Vl2lwaXcQivwQERwQiwGMctT0F_nYYpBRGywiWKkcr-GiZzsQdXZMiAaNvHerMGItuDhSr2mlhEqhy8j3qBrWdt6xLcI/s640/52_Blue_theme.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
15. 切換到 Dark theme。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;53_Dark_theme&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3kFrbvB3NcjVDzst05Jb8JEiM2k0aqeUNa-BcR0IFa1uWLHSbatloLrUfPsda_mzBYtYQYT44ZO9sSxH8-jPrLkHWDR3kaQ3v2xJ4_E4EKQZkbndrsrBMPYMHCkT1OwVdPipmgOEIIrw/s1600/53_Dark_theme.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="751" data-original-width="1314" height="364" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3kFrbvB3NcjVDzst05Jb8JEiM2k0aqeUNa-BcR0IFa1uWLHSbatloLrUfPsda_mzBYtYQYT44ZO9sSxH8-jPrLkHWDR3kaQ3v2xJ4_E4EKQZkbndrsrBMPYMHCkT1OwVdPipmgOEIIrw/s640/53_Dark_theme.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
16. 若要全部都 黑化，可以改用 Visual Studio Code 或&amp;nbsp;SQL Ops Studio 等。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;61_Dark_default_dark&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWvmBgeeqv3ehN_Pe-bl2S_QjsRnSaGHRtyT-mtbnaDXuQ4B0TYRxsXC3mUf5nEReEvdKWVmBaw11dwQn1Rgb_xSYpU8olVZxUsO8FZ6nLuMbkRJjx2qX9Cp1mW5kV00we_DWFSNjrBLA/s1600/61_Dark_default_dark.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="768" data-original-width="1024" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWvmBgeeqv3ehN_Pe-bl2S_QjsRnSaGHRtyT-mtbnaDXuQ4B0TYRxsXC3mUf5nEReEvdKWVmBaw11dwQn1Rgb_xSYpU8olVZxUsO8FZ6nLuMbkRJjx2qX9Cp1mW5kV00we_DWFSNjrBLA/s640/61_Dark_default_dark.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Reference&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
SQL Ops Studio: Selecting the Color Theme - Dark theme&lt;br /&gt;
&lt;a href="http://sharedderrick.blogspot.com/2018/04/sql-ops-selecting-color-theme-dark-theme.html"&gt;http://sharedderrick.blogspot.com/2018/04/sql-ops-selecting-color-theme-dark-theme.html&lt;/a&gt;</description><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIpcrQBP4YViq70m0EnX6jsAd0pGe5J2p7aBo4aG7sALgIc6p7WWP5GByxP5k6Mtnbb2uSKxzunaHi-Ei6rLeWcO4uSm1agnlOLCgHR433qPV_6_xt0mWioDvu9bi_wlfjPn3bVjfWans/s72-c/31_SSMS.png" width="72"/><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><title>[SQL Server] CREATE OR ALTER - New enhancements in SQL Server 2016 SP1</title><link>http://sharedderrick.blogspot.com/2018/07/sql-server-create-or-alter-new.html</link><category>SQL Server</category><category>SQL Server 2016</category><author>noreply@blogger.com (DerrickLaLa)</author><pubDate>Sat, 14 Jul 2018 14:01:00 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1420955872914622499.post-782182568113026891</guid><description>&lt;br /&gt;
&lt;br /&gt;
SQL Server 2016 (13.x) SP1 與 Azure SQL Database&amp;nbsp;開始支援&amp;nbsp;&lt;b&gt;&lt;span style="color: blue;"&gt;CREATE OR ALTER&lt;/span&gt;&lt;/b&gt;。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;僅需 1 句 T-SQL，即可自動判斷是該 CREATE 或 ALTER 此 Stored Procedure。&lt;/li&gt;
&lt;li&gt;無需額外撰寫判斷式去檢查是否存在於 sys.objects 中。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
CREATE OR ALTER 支援以下物件：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;STORED PROCEDURES&lt;/li&gt;
&lt;li&gt;FUNCTIONS&lt;/li&gt;
&lt;li&gt;TRIGGERS&lt;/li&gt;
&lt;li&gt;VIEWS&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh92wEJ0EMOgVM5JenHQwj-2zx7oqeGwNDYyLEKOeaw966dYWXsjmYh0s5FUwTjq3rymsKTT5JWkFjkaoYaYw2c3-PIudrpN_-gbAteT0qoWzJafCrhgo2kWoZRVTxh4FY7hbjx3RDRmT8/s1600/04_Compare_All.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="778" data-original-width="1256" height="396" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh92wEJ0EMOgVM5JenHQwj-2zx7oqeGwNDYyLEKOeaw966dYWXsjmYh0s5FUwTjq3rymsKTT5JWkFjkaoYaYw2c3-PIudrpN_-gbAteT0qoWzJafCrhgo2kWoZRVTxh4FY7hbjx3RDRmT8/s640/04_Compare_All.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
不受限於 COMPATIBILITY_LEVEL。&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;&lt;b&gt;CREATE OR ALTER&lt;/b&gt; - New enhancements in SQL Server 2016 SP1&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
01. 僅需 1 句 T-SQL，即可自動判斷是該 CREATE 或 ALTER 此 Stored Procedure。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;CREATE OR ALTER&lt;/span&gt; &lt;span style="color: blue;"&gt;PROC&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;無需額外撰寫判斷式去檢查是否存在於&amp;nbsp;sys.objects 中。&lt;/li&gt;
&lt;li&gt;SQL Server 2016 (13.x) &lt;b&gt;&lt;span style="color: blue;"&gt;SP1&lt;/span&gt;&lt;/b&gt; 支援。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;01_CREATE OR ALTER PROC&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiN1vPxYcEznLllZX_HDvcdTiywzkKQRfS2Q_LZJD_NHmCWcWFyqtYzjXJwV1mbzyVK3MEU2O_uqkYJvtmQ4Vb2OBgIrvEoz3oV5tpQkglVniRlrIdGU_03bz2cvIK1pvAZQNbwEqbYVcw/s1600/01_CREATE+OR+ALTER+PROC.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="186" data-original-width="377" height="314" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiN1vPxYcEznLllZX_HDvcdTiywzkKQRfS2Q_LZJD_NHmCWcWFyqtYzjXJwV1mbzyVK3MEU2O_uqkYJvtmQ4Vb2OBgIrvEoz3oV5tpQkglVniRlrIdGU_03bz2cvIK1pvAZQNbwEqbYVcw/s640/01_CREATE+OR+ALTER+PROC.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 精簡的判斷式，但仍需額外再寫 CREATE PROC。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;DROP PROCEDURE IF EXISTS&lt;/span&gt; 。&lt;/li&gt;
&lt;li&gt;無需增加判斷式去檢查是否存在於 sys.objects 中。&lt;/li&gt;
&lt;li&gt;SQL Server 2016 (13.x) 支援。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;02_DROP PROCEDURE IF EXISTS&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqjVI7rKgibzhs3Ka3PpLTSuOV17C2ye1Cz-29CVQEile_zv33QSFjMah1GaDH1iwER4_Ktc2tPz7A9WSKTcYw9kWTyNrv1H5lWraoWLzwGBNGoG73wQVtXD5k9bFuFsOkDvHBn6OG0sw/s1600/02_DROP+PROCEDURE+IF+EXISTS.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="237" data-original-width="503" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqjVI7rKgibzhs3Ka3PpLTSuOV17C2ye1Cz-29CVQEile_zv33QSFjMah1GaDH1iwER4_Ktc2tPz7A9WSKTcYw9kWTyNrv1H5lWraoWLzwGBNGoG73wQVtXD5k9bFuFsOkDvHBn6OG0sw/s640/02_DROP+PROCEDURE+IF+EXISTS.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 額外撰寫判斷式去檢查是否存在於 sys.objects 中。SQL Server 2016 之前的語法。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;03_EXISTS_sys_objects&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXEGnMemfHmkXDLp2bT35ZHdIrW1z5JyUwHaHsEUlWMEFrwgv3G-ZpKkvJq3zXtuuHkpALQe-OI8Fb7mhVnwRILzyuu2-JAJKZ5z2jmOtV9nWnVBBAd8r3RSoTIF5sAhE7Ps3cxiCGzmM/s1600/03_EXISTS_sys_objects.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="316" data-original-width="1263" height="160" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXEGnMemfHmkXDLp2bT35ZHdIrW1z5JyUwHaHsEUlWMEFrwgv3G-ZpKkvJq3zXtuuHkpALQe-OI8Fb7mhVnwRILzyuu2-JAJKZ5z2jmOtV9nWnVBBAd8r3RSoTIF5sAhE7Ps3cxiCGzmM/s640/03_EXISTS_sys_objects.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
04. 綜合來看：&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;SQL Server 2016 (13.x) SP1 支援的 &lt;b&gt;&lt;span style="color: blue;"&gt;CREATE OR ALTER&lt;/span&gt;&lt;/b&gt; ，最為簡潔。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;04_Compare_All&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNBD0TZqL9nd9BJe2-pt1rWCEO1sipD7XpydqDSpV2CR9V09PvHvRRoY6__nu7acXrPET3ZLhlGP1yLOQtyDR_0ybgNSjnH-mMztKPEMa4xAMsZwQx8FU0w5HPraaHrajlMStwjA9nlqI/s1600/04_Compare_All.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="778" data-original-width="1256" height="396" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNBD0TZqL9nd9BJe2-pt1rWCEO1sipD7XpydqDSpV2CR9V09PvHvRRoY6__nu7acXrPET3ZLhlGP1yLOQtyDR_0ybgNSjnH-mMztKPEMa4xAMsZwQx8FU0w5HPraaHrajlMStwjA9nlqI/s640/04_Compare_All.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;CREATE OR ALTER 支援的物件&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
CREATE OR ALTER 支援以下物件：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;STORED PROCEDURES&lt;/li&gt;
&lt;li&gt;FUNCTIONS&lt;/li&gt;
&lt;li&gt;TRIGGERS&lt;/li&gt;
&lt;li&gt;VIEWS&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
01. &lt;span style="color: blue;"&gt;CREATE OR ALTER PROC&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;11_CREATE OR ALTER PROC&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhN6dCiTkWH8eIIbnE2dIWaB1MSJn5KytdeOrqWV9w1Q231G94uZIwVgMRFQX8UXQP4Sh3jeAN_anRFuyYHa3ZFiTvxy2aCDaSVdr9VPvoLrzRNjEqPgq_jqnxtN7FIXktCFmy2fO-IQig/s1600/11_CREATE+OR+ALTER+PROC.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="403" data-original-width="428" height="602" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhN6dCiTkWH8eIIbnE2dIWaB1MSJn5KytdeOrqWV9w1Q231G94uZIwVgMRFQX8UXQP4Sh3jeAN_anRFuyYHa3ZFiTvxy2aCDaSVdr9VPvoLrzRNjEqPgq_jqnxtN7FIXktCFmy2fO-IQig/s640/11_CREATE+OR+ALTER+PROC.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. &lt;span style="color: blue;"&gt;CREATE OR ALTER FUNCTION&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;12_CREATE OR ALTER FUNCTION&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixvNEYHHzpfQPtuSis4jqnESYGhzk7s5_-kotNV6kDSqYtWM1jRIiGpOtP4UnNDSp6Z72osG3tpLX8_yJAdrQRdR6um5oOboFRyLMpIRdUAWdQw_VCZKGtwE5SsSupv5EKEijV96wA1d8/s1600/12_CREATE+OR+ALTER+FUNCTION.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="407" data-original-width="536" height="484" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixvNEYHHzpfQPtuSis4jqnESYGhzk7s5_-kotNV6kDSqYtWM1jRIiGpOtP4UnNDSp6Z72osG3tpLX8_yJAdrQRdR6um5oOboFRyLMpIRdUAWdQw_VCZKGtwE5SsSupv5EKEijV96wA1d8/s640/12_CREATE+OR+ALTER+FUNCTION.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. &lt;span style="color: blue;"&gt;CREATE OR ALTER VIEW&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;13_CREATE OR ALTER VIEW&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhurApyAYDRWec-4pnGDz-KDZL6b2aNMJBf4shBPt3RqLSbddENi5Mb39WL1_tMjInpLQ0ifJwqHAH1PBpJCRL1RP46WZx7uoyMKYSg30fmSYTAgcA1WHS9t9ue9gtP2Q5k3_mxtXGbr_w/s1600/13_CREATE+OR+ALTER+VIEW.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="330" data-original-width="492" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhurApyAYDRWec-4pnGDz-KDZL6b2aNMJBf4shBPt3RqLSbddENi5Mb39WL1_tMjInpLQ0ifJwqHAH1PBpJCRL1RP46WZx7uoyMKYSg30fmSYTAgcA1WHS9t9ue9gtP2Q5k3_mxtXGbr_w/s640/13_CREATE+OR+ALTER+VIEW.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
04. &lt;span style="color: blue;"&gt;CREATE OR ALTER TRIGGER&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;14_CREATE OR ALTER TRIGGER&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6mSgmOVN3LXn7H1sr8IwDD20P5UsxRAHU7TCtF-i-09cUuLCaOg1W0gFrxgrprxKvPcJtSz27xWWSw_Ucx5-cLGrrXE6mqx7CP5Mh1N6W9Wb8oqMZ5n5H0fl_j0YeuL7W_ycAH-T_kCU/s1600/14_CREATE+OR+ALTER+TRIGGER.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="387" data-original-width="458" height="540" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6mSgmOVN3LXn7H1sr8IwDD20P5UsxRAHU7TCtF-i-09cUuLCaOg1W0gFrxgrprxKvPcJtSz27xWWSw_Ucx5-cLGrrXE6mqx7CP5Mh1N6W9Wb8oqMZ5n5H0fl_j0YeuL7W_ycAH-T_kCU/s640/14_CREATE+OR+ALTER+TRIGGER.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Sample Code&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
20180714_CREATE OR ALTER&lt;br /&gt;
&lt;a href="https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing"&gt;https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Reference&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
CREATE OR ALTER – another great language enhancement in SQL Server 2016 SP1&lt;br /&gt;
&lt;a href="https://blogs.msdn.microsoft.com/sqlserverstorageengine/2016/11/17/create-or-alter-another-great-language-enhancement-in-sql-server-2016-sp1/"&gt;https://blogs.msdn.microsoft.com/sqlserverstorageengine/2016/11/17/create-or-alter-another-great-language-enhancement-in-sql-server-2016-sp1/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Update introduces CREATE OR ALTER Transact-SQL statement in SQL Server 2016&lt;br /&gt;
&lt;a href="https://support.microsoft.com/en-us/help/3190548/update-introduces-create-or-alter-transact-sql-statement-in-sql-server"&gt;https://support.microsoft.com/en-us/help/3190548/update-introduces-create-or-alter-transact-sql-statement-in-sql-server&lt;/a&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</description><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh92wEJ0EMOgVM5JenHQwj-2zx7oqeGwNDYyLEKOeaw966dYWXsjmYh0s5FUwTjq3rymsKTT5JWkFjkaoYaYw2c3-PIudrpN_-gbAteT0qoWzJafCrhgo2kWoZRVTxh4FY7hbjx3RDRmT8/s72-c/04_Compare_All.png" width="72"/><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><title>[SQL Server] 1,700 bytes and 32 columns for nonclustered index</title><link>http://sharedderrick.blogspot.com/2018/07/sql-server-1700-bytes-and-32-columns.html</link><author>noreply@blogger.com (DerrickLaLa)</author><pubDate>Thu, 12 Jul 2018 22:11:00 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1420955872914622499.post-929886978504662347</guid><description>&lt;br /&gt;
SQL Server 2016 (13.x) 與 Azure SQL Database 增強 Nonclustered Index(非叢集索引)：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;資料長度延展為 &lt;b&gt;&lt;span style="color: blue;"&gt;1,700&lt;/span&gt;&lt;/b&gt; Bytes，由 &lt;b&gt;&lt;span style="color: blue;"&gt;32&lt;/span&gt;&lt;/b&gt; 個 Column 組成。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
先前版本是：&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;資料長度為 &lt;span style="color: #274e13;"&gt;&lt;b&gt;900&lt;/b&gt;&lt;/span&gt; Bytes，由 &lt;span style="color: #274e13;"&gt;&lt;b&gt;16&lt;/b&gt;&lt;/span&gt; 個 Column 組成。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
Clustered Index(叢集索引) 仍是 &lt;span style="color: blue;"&gt;&lt;b&gt;900&lt;/b&gt;&lt;/span&gt; Bytes。&lt;br /&gt;
&lt;br /&gt;
若有需要超過，請改用 Included Columns (內含資料行的索引)&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;[SQL Server] 1,700 bytes and 32 columns for nonclustered index&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
01. 建立資料表:&amp;nbsp;NonCL_Size&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;NCL VARCHAR(&lt;b&gt;&lt;span style="color: red;"&gt;2048&lt;/span&gt;&lt;/b&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
並建立&amp;nbsp;NonClustered Index&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;11_Create NonClustered Index_Maximum_1700&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhW9MeGwhAepsMS9e3hXqTb5xbPFh0a9TUEaUqz6sde8SlfUEIPGGleDPA0_HgbbMNM_truHnmIOYRPCmIAZR_7uY7R79Q_gtzuYt3Ttm6EJuJ3SWCTgw8Z33nve1ACOUcmVCiMXoA25jo/s1600/11_Create+NonClustered+Index_Maximum_1700.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="397" data-original-width="779" height="326" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhW9MeGwhAepsMS9e3hXqTb5xbPFh0a9TUEaUqz6sde8SlfUEIPGGleDPA0_HgbbMNM_truHnmIOYRPCmIAZR_7uY7R79Q_gtzuYt3Ttm6EJuJ3SWCTgw8Z33nve1ACOUcmVCiMXoA25jo/s640/11_Create+NonClustered+Index_Maximum_1700.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;span style="color: blue;"&gt;Warning! The maximum key length for a nonclustered index is 1700 bytes.&amp;nbsp;&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;span style="color: blue;"&gt;The index 'ix_NCL' has maximum length of 2048 bytes.&amp;nbsp;&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;span style="color: blue;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;
&lt;i&gt;&lt;span style="color: blue;"&gt;For some combination of large values, the insert/update operation will fail.&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
02. 輸入資料:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;第 1 筆，資料長度是 &lt;span style="color: blue;"&gt;&lt;b&gt;1700 &lt;/b&gt;&lt;/span&gt;bytes，沒有超過 Nonclustered Indexes 上限。&lt;/li&gt;
&lt;li&gt;第 2 筆，資料長度是 &lt;span style="color: red;"&gt;&lt;b&gt;1701 &lt;/b&gt;&lt;/span&gt;bytes，超過 Nonclustered Indexes 上限，導致新增失敗。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
-- figure&amp;nbsp;12_Operation failed_over_1700&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRdaTHgHCNjrxwnXBxW69DDPXIPCJKxbkQQbB7BatGUzQdsYWW4KU7OTTD2qhfyp-m22f0426e7-dzVCOBvYF6sNnz2u4z1Y_-5JqJGhSlbaNtmx7R9fMXEGwRllGAlTUq5qzVekg_k9s/s1600/12_Operation+failed_over_1700.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="312" data-original-width="1289" height="154" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRdaTHgHCNjrxwnXBxW69DDPXIPCJKxbkQQbB7BatGUzQdsYWW4KU7OTTD2qhfyp-m22f0426e7-dzVCOBvYF6sNnz2u4z1Y_-5JqJGhSlbaNtmx7R9fMXEGwRllGAlTUq5qzVekg_k9s/s640/12_Operation+failed_over_1700.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;span style="color: red;"&gt;Msg 1946, Level 16, State 3, Line 32&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;span style="color: red;"&gt;Operation failed.&amp;nbsp;&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;span style="color: red;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;
&lt;i&gt;&lt;span style="color: red;"&gt;The index entry of length 1701 bytes for the index 'ix_NCL' exceeds the maximum length of 1700 bytes for nonclustered indexes.&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
03. 查詢資料表，確認僅 第 1 筆 輸入成功。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;13_Only 1 row&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9k2ag8eyHYvBE6e-OIiB_83zwFkfvO6GB5w7IeLjJmyWO-mVTbSqHW4N2OHi1Zm_fF1cLiv3o1sJ_ufCYV4B_8wQk5P2rhXT3H2TnZc8C4xAcjTjomggpMk0H-v5iTCMMOYQf-SExFRQ/s1600/13_Only+1+row.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="193" data-original-width="477" height="258" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9k2ag8eyHYvBE6e-OIiB_83zwFkfvO6GB5w7IeLjJmyWO-mVTbSqHW4N2OHi1Zm_fF1cLiv3o1sJ_ufCYV4B_8wQk5P2rhXT3H2TnZc8C4xAcjTjomggpMk0H-v5iTCMMOYQf-SExFRQ/s640/13_Only+1+row.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
04.&amp;nbsp; 建立資料表:&amp;nbsp;CL_Size&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;CL VARCHAR(&lt;b&gt;&lt;span style="color: red;"&gt;1024&lt;/span&gt;&lt;/b&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
建立&amp;nbsp;Clustered Index&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;21_Create Clustered Index_Maximum_900&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg06qf25-nENl0-pA4GREyKYiuL_ZAGaasXF6pKuT-vjCz85szTXdof0-FFdOIPmAhOlIqkQKxuiaKStnUABbGCeMSfnMKSbNMNX0uEx45uOni7NmmHyoLvoyTwN8cIC8oIyDvp0oOeCCs/s1600/21_Create+Clustered+Index_Maximum_900.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="405" data-original-width="801" height="322" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg06qf25-nENl0-pA4GREyKYiuL_ZAGaasXF6pKuT-vjCz85szTXdof0-FFdOIPmAhOlIqkQKxuiaKStnUABbGCeMSfnMKSbNMNX0uEx45uOni7NmmHyoLvoyTwN8cIC8oIyDvp0oOeCCs/s640/21_Create+Clustered+Index_Maximum_900.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;span style="color: blue;"&gt;Warning! The maximum key length for a clustered index is 900 bytes.&amp;nbsp;&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;span style="color: blue;"&gt;The index 'ix_CL' has maximum length of 1024 bytes.&amp;nbsp;&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;span style="color: blue;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;
&lt;i&gt;&lt;span style="color: blue;"&gt;For some combination of large values, the insert/update operation will fail.&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
05. 輸入資料:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
第 1 筆，資料長度是 &lt;span style="color: blue;"&gt;&lt;b&gt;900 &lt;/b&gt;&lt;/span&gt;bytes，沒有超過 Clustered Indexes 上限。&lt;br /&gt;
第 2 筆，資料長度是 &lt;b&gt;&lt;span style="color: red;"&gt;901 &lt;/span&gt;&lt;/b&gt;bytes，超過 Clustered Indexes 上限，導致新增失敗。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;22_Operation failed_over_900&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtHieb-Fl3Du0uArMy7O7a8Uv9k1etMScAqZr2EEImRxNRilgBGVEqmrzrf413cu8XxIFm4x81LrcBGvm5uglQkVTpeA6DaghcJ-W31k91Y8dZx6ZbnrFra3tjqW6UqLY4UvFszn3VSD0/s1600/22_Operation+failed_over_900.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="351" data-original-width="1237" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtHieb-Fl3Du0uArMy7O7a8Uv9k1etMScAqZr2EEImRxNRilgBGVEqmrzrf413cu8XxIFm4x81LrcBGvm5uglQkVTpeA6DaghcJ-W31k91Y8dZx6ZbnrFra3tjqW6UqLY4UvFszn3VSD0/s640/22_Operation+failed_over_900.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;span style="color: red;"&gt;Msg 1946, Level 16, State 3, Line 72&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;span style="color: red;"&gt;Operation failed.&amp;nbsp;&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;span style="color: red;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;
&lt;i&gt;&lt;span style="color: red;"&gt;The index entry of length 901 bytes for the index 'ix_CL' exceeds the maximum length of 900 bytes for clustered indexes.&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
06. 查詢資料表，確認僅 第 1 筆 輸入成功。&lt;br /&gt;
&lt;br /&gt;
-- figure&amp;nbsp;23_Only 1 row&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI3A1JokJBlyvZL0KbNNrHWeZpZwirGPhoCS4WXP-ZVwjniQTfG0zpRc3QwAJdtXXbZ48Ol-qXfT2erFgTEA0M9J_Sd7TX00JoLbrl1sGGy3pmQYy9hW2Pbz6ljAr5t-gu6BLi6KLzWH0/s1600/23_Only+1+row.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="205" data-original-width="446" height="292" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI3A1JokJBlyvZL0KbNNrHWeZpZwirGPhoCS4WXP-ZVwjniQTfG0zpRc3QwAJdtXXbZ48Ol-qXfT2erFgTEA0M9J_Sd7TX00JoLbrl1sGGy3pmQYy9hW2Pbz6ljAr5t-gu6BLi6KLzWH0/s640/23_Only+1+row.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
SQL Server 2016 與 Azure SQL Database 增強 nonclustered index(非叢集索引)，將資料長度延展為 1,700 Bytes，先前版本是 900 Bytes。&lt;br /&gt;
&lt;br /&gt;
Clustered Index(叢集索引)為 900 個位元組數。 Nonclustered Index(非叢集索引) 為 1,700 Bytes。&lt;br /&gt;
&lt;br /&gt;
您可以使用大小上限增加超過限制的可變長度資料行，來定義索引鍵。&lt;br /&gt;
不過，這些資料行中的資料大小總和不得超過限制。&lt;br /&gt;
&lt;br /&gt;
在非叢集索引中，您可以包含額外的非索引鍵資料行，這些資料行不會計入索引鍵的大小限制。&lt;br /&gt;
非索引鍵資料行可能有助於提升某些查詢的執行效能。&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Sample Code&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
20180712_1700byte_32column_Nonclustered&lt;br /&gt;
&lt;a href="https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing"&gt;https://drive.google.com/drive/folders/0B9PQZW3M2F40OTk3YjI2NTEtNjUxZS00MjNjLWFkYWItMzg4ZDhhMGIwMTZl?usp=sharing&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-large;"&gt;Reference&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Maximum Capacity Specifications for SQL Server&lt;br /&gt;
&lt;a href="https://docs.microsoft.com/en-us/sql/sql-server/maximum-capacity-specifications-for-sql-server?view=sql-server-2017"&gt;https://docs.microsoft.com/en-us/sql/sql-server/maximum-capacity-specifications-for-sql-server?view=sql-server-2017&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Increased nonclustered index key size with SQL Server 2016&lt;br /&gt;
&lt;a href="https://blogs.msdn.microsoft.com/sqlserverstorageengine/2016/04/26/increased-nonclustered-index-key-size-with-sql-server-2016/"&gt;https://blogs.msdn.microsoft.com/sqlserverstorageengine/2016/04/26/increased-nonclustered-index-key-size-with-sql-server-2016/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Create Indexes with Included Columns&lt;br /&gt;
&lt;a href="https://docs.microsoft.com/en-us/sql/relational-databases/indexes/create-indexes-with-included-columns?view=sql-server-2017"&gt;https://docs.microsoft.com/en-us/sql/relational-databases/indexes/create-indexes-with-included-columns?view=sql-server-2017&lt;/a&gt;</description><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhW9MeGwhAepsMS9e3hXqTb5xbPFh0a9TUEaUqz6sde8SlfUEIPGGleDPA0_HgbbMNM_truHnmIOYRPCmIAZR_7uY7R79Q_gtzuYt3Ttm6EJuJ3SWCTgw8Z33nve1ACOUcmVCiMXoA25jo/s72-c/11_Create+NonClustered+Index_Maximum_1700.png" width="72"/><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item></channel></rss>