sql 優化 連接提示 查詢提示 標提示

SQL Server的查詢優化器在select查詢執行的時候產生一個高效的查詢執行計劃。若是優化器不能選擇最優的計劃,那麼就須要檢查查詢計劃、統計信息、支持的索引等,而經過使用提示能夠改變優化器選擇查詢計劃的工程,使優化器生成一個更好的執行計劃。sql

一、聯接提示數據庫

<join_hint> ::=      { LOOP | HASH | MERGE | REMOTE }express

LOOP | HASH | MERGE

指定查詢中的聯接應使用循環、哈希或合併。 使用 LOOP |HASH | MERGE JOIN 在兩個表之間強制執行特定聯接。 不能同時將 LOOP 與 RIGHT(或 FULL)指定爲聯接類型。數組

REMOTE

指定聯接操做在右表處執行。 這在左表是本地表而右表是遠程表的狀況下頗有用。 只在左表的行數少於右錶行數時才能使用 REMOTE。緩存

若是右表爲本地表,則聯接在本地執行。 若是兩個表均爲遠程表但來自不一樣的數據源,則 REMOTE 將使聯接在右表處執行。 若是兩個表均爲遠程表且來自相同數據源,則不須要使用 REMOTE。服務器

若是使用 COLLATE 子句將聯接謂詞中比較的值中的一個值轉換成了不一樣的排序規則,則不能使用 REMOTE。REMOTE 只可用於 INNER JOIN 操做。session

  1. --沒有提示的查詢 
  2. select
  3. from Production.Product p  
  4. innerjoin production.productreview r 
  5.        on r.productid = p.productid 
  6.  
  7.  
  8. --Loop適合:當一個表很小另外一個表很大、在關聯的列上有索引時 
  9. select
  10. from Production.Product p  
  11. inner loop join production.productreview r  
  12.               on r.productid = p.productid 
  13.  
  14.  
  15. --merge適合:按照關聯列排序的中等或者大的表        
  16. select
  17. from Production.Product p 
  18. inner merge join production.productreview r 
  19.               on r.productid = p.productid 
  20.  
  21. --hash適合:沒有排序的大的表 
  22. select
  23. from Production.Product p 
  24. inner hash join production.productreview r 
  25.              on r.productid = p.productid     
  26.               
--沒有提示的查詢
select *
from Production.Product p 
inner join production.productreview r
       on r.productid = p.productid


--Loop適合:當一個表很小另外一個表很大、在關聯的列上有索引時
select *
from Production.Product p 
inner loop join production.productreview r 
              on r.productid = p.productid


--merge適合:按照關聯列排序的中等或者大的表       
select *
from Production.Product p
inner merge join production.productreview r
              on r.productid = p.productid

--hash適合:沒有排序的大的表
select *
from Production.Product p
inner hash join production.productreview r
             on r.productid = p.productid    
             

二、查詢提示與表提示架構

          

<query_hint > ::= 
{ { HASH | ORDER } GROUP 
  | { CONCAT | HASH | MERGE } UNION 
  | { LOOP | MERGE | HASH } JOIN 
  | EXPAND VIEWS 
  | FAST number_rows 
  | FORCE ORDER 
  | IGNORE_NONCLUSTERED_COLUMNSTORE_INDEX
  | KEEP PLAN 
  | KEEPFIXED PLAN
  | MAXDOP number_of_processors 
  | MAXRECURSION number 
  | OPTIMIZE FOR ( @variable_name { UNKNOWN | = literal_constant } [ , ...n ] )
  | OPTIMIZE FOR UNKNOWN
  | PARAMETERIZATION { SIMPLE | FORCED }
  | RECOMPILE
  | ROBUST PLAN 
  | USE PLAN N'xml_plan'
  | TABLE HINT ( exposed_object_name [ , <table_hint> [ [, ]...n ] ] )
}

<table_hint> ::=
[ NOEXPAND ] { 
    INDEX ( index_value [ ,...n ] ) | INDEX = ( index_value )
  | FORCESEEK [( index_value ( index_column_name [,... ] ) ) ]
  | FORCESCAN
  | HOLDLOCK 
  | NOLOCK 
  | NOWAIT
  | PAGLOCK 
  | READCOMMITTED 
  | READCOMMITTEDLOCK 
  | READPAST 
  | READUNCOMMITTED 
  | REPEATABLEREAD 
  | ROWLOCK 
  | SERIALIZABLE 
  | SPATIAL_WINDOW_MAX_CELLS = integer
  | TABLOCK 
  | TABLOCKX 
  | UPDLOCK 
  | XLOCK

查詢提示的參數併發

{ HASH | ORDER } GROUP

指定在查詢的 GROUP BY 或 DISTINCT 子句中所說明的聚合應使用哈希或排列。ide

{ MERGE | HASH | CONCAT } UNION

指定全部 UNION 運算由合併、哈希或串聯 UNION 集執行。 若是指定了多個 UNION 提示,查詢優化器就會從這些指定的提示中選擇開銷最少的策略。

{ LOOP | MERGE | HASH } JOIN

指定整個查詢中的全部聯接操做由 LOOP JOIN、MERGE JOIN 或 HASH JOIN 執行。若是指定了多個聯接提示,則優化器從容許的聯接策略中選擇開銷最少的聯接策略。

若是在同一查詢中的 FROM 子句中還爲一對特定的表指定了聯接提示,則儘管仍須遵照查詢提示,但該聯接提示將優先聯接這兩個表。所以,這對錶的聯接提示可能只限制選擇查詢提示中容許的聯接方法。有關詳細信息,請參閱聯接提示 (Transact-SQL)

EXPAND VIEWS

指定展開索引視圖,並且查詢優化器不將任何索引視圖看做是查詢中任何部分的替代。當視圖名稱由查詢文本中的視圖定義替換時,視圖將展開。

實際上,該查詢提示不容許在查詢計劃中直接使用索引視圖和直接在索引視圖上使用索引。

只有在查詢的 SELECT 部分中直接引用視圖,並且指定了 WITH (NOEXPAND) 或 WITH (NOEXPAND, INDEX(index_value [,...n ] ) ) 時,纔不展開索引視圖。有關查詢提示 WITH (NOEXPAND) 的詳細信息,請參閱FROM

只有語句的 SELECT 部分中的視圖(包括 INSERT、UPDATE、MERGE 和 DELETE 語句中的視圖)才受提示影響。

FAST number_rows

指定對查詢進行優化,以便快速檢索第一個 number_rows.。該值是非負整數。在返回第一個number_rows 後,查詢繼續執行並生成完整的結果集。

FORCE ORDER

指定在查詢優化過程當中保持由查詢語法指示的聯接順序。 使用 FORCE ORDER 不會影響查詢優化器可能的角色逆轉行爲。

注意注意

在 MERGE 語句中,若是未指定 WHEN SOURCE NOT MATCHED 子句,則按照默認的聯接次序,先訪問源表再訪問目標表。若是指定 FORCE ORDER,則保留此默認行爲。

KEEP PLAN

強制查詢優化器對查詢放寬估計的從新編譯閾值。 當經過運行 UPDATE、DELETE、MERGE 或 INSERT 語句對錶進行的索引列更改數目達到估計數目時,會自動從新編譯查詢,該估計數目即爲估計的從新編譯閾值。指定 KEEP PLAN 可確保當表有多個更新時不會頻繁地對查詢進行從新編譯。

KEEPFIXED PLAN

強制查詢優化器不因統計信息的更改而從新編譯查詢。 指定 KEEPFIXED PLAN 可確保僅當更改基礎表的架構或在那些表上執行 sp_recompile 時才從新編譯查詢。

IGNORE_NONCLUSTERED_COLUMNSTORE_INDEX

可防止查詢使用非彙集的 xVelocity 內存優化的列存儲索引。 若是查詢包含避免使用 columnstore 索引的查詢提示以及有關使用 columnstore 索引的索引提示,則這些提示將發生衝突,查詢將返回錯誤。

MAXDOP number

對於指定了 max degree of parallelism 配置選項的查詢,會覆蓋sp_configure 和資源調控器的該選項。MAXDOP 查詢提示能夠超出使用 sp_configure 配置的值。若是 MAXDOP 超出使用資源調控器配置的值,則數據庫引擎會使用資源調控器 MAXDOP 值(如ALTER WORKLOAD GROUP (Transact-SQL) 中所述)。當使用 MAXDOP 查詢提示時,全部和max degree of parallelism配置選項一塊兒使用的語義規則均適用。有關詳細信息,請參閱配置 max degree of parallelism 服務器配置選項

注意事項注意

若是 MAXDOP 設置爲零,服務器將選擇最大並行度。

MAXRECURSION number

指定該查詢容許的最大遞歸數。 number 是介於 0 至 32767 之間的非負整數。 若是指定 0,則沒有限制。 若是未指定此選項,則對服務器的默認限制爲 100。

當在查詢執行期間達到指定或默認的 MAXRECURSION 數量限制時,將結束查詢並返回錯誤。

因爲此錯誤,該語句的全部結果都被回滾。 若是該語句爲 SELECT 語句,則可能會返回部分結果或不返回結果。 所返回的任何部分結果均可能沒法包括超過指定最大遞歸級別的遞歸級別上的全部行。

有關詳細信息,請參閱 WITH common_table_expression (Transact-SQL)

OPTIMIZE FOR ( @variable_name { UNKNOWN | =literal_constant } [, ...n] )

在編譯和優化查詢時指示查詢優化器對局部變量使用特定值。 僅在查詢優化期間使用該值,在查詢執行期間不使用該值。

@variable_name

在查詢中使用的局部變量的名稱,能夠爲其分配用於 OPTIMIZE FOR 查詢提示的值。

UNKNOWN

指定查詢優化器在查詢優化期間使用統計數據而不是初始值來肯定局部變量的值。

literal_constant

要分配給 @variable_name 並用於 OPTIMIZE FOR 查詢提示的文字常量值。literal_constant 只在查詢優化期間使用,在查詢執行期間不用做@variable_name的值。 literal_constant 能夠是任意可用文字常量表示的 SQL Server 系統數據類型。literal_constant 的數據類型必須可隱式轉換爲查詢中@variable_name所引用的數據類型。

OPTIMIZE FOR 能夠抵消優化器的默認參數檢測行爲,也可在建立計劃指南時使用。有關詳細信息,請參閱從新編譯存儲過程

OPTIMIZE FOR UNKNOWN

指示查詢優化器在編譯和優化查詢時使用全部局部變量的統計數據而不是初始值,包括使用強制參數化建立的參數。

若是在同一查詢提示中使用 OPTIMIZE FOR @variable_name = literal_constant 和 OPTIMIZE FOR UNKNOWN,則查詢優化器對特定值使用指定的 literal_constant,而對其他變量值使用 UNKNOWN。 這些值僅用於查詢優化期間,而不會用於查詢執行期間。

PARAMETERIZATION { SIMPLE | FORCED }

指定在編譯查詢時 SQL Server 查詢優化器應用於此查詢的參數化規則。

重要說明重要提示

PARAMETERIZATION 查詢提示只能在計劃指南中指定。 不能直接在查詢中指定該查詢提示。

SIMPLE 用於指示查詢優化器嘗試進行簡單參數化。 FORCED 用於指示優化器嘗試進行強制參數化。 PARAMETERIZATION 查詢提示用於覆蓋計劃指南中 PARAMETERIZATION 數據庫 SET 選項的當前設置。有關詳細信息,請參閱使用計劃指南指定查詢參數化行爲

RECOMPILE

指示 SQL Server 數據庫引擎在執行爲查詢生成的計劃後將其丟棄,從而在下次執行同一查詢時強制查詢優化器從新編譯查詢計劃。若是未指定 RECOMPILE,數據庫引擎將緩存查詢計劃並從新使用它們。在編譯查詢計劃時,RECOMPILE 查詢提示將使用查詢中任意本地變量的當前值,若是查詢位於存儲過程當中,這些當前值將傳遞給任意參數。

在只須從新編譯存儲過程當中的一部分查詢,而不是從新編譯整個存儲過程時,RECOMPILE 是建立使用 WITH RECOMPILE 子句的存儲過程的頗有用的替代方法。有關詳細信息,請參閱從新編譯存儲過程在建立計劃指南時,RECOMPILE 也頗有用。

ROBUST PLAN

強制查詢優化器嘗試一個計劃,該計劃可能以性能爲代價得到最大可能的行大小。 處理查詢時,中間表和運算符可能須要存儲和處理比輸入行寬的行。 在有些狀況下,行可能很寬,以至某個運算符沒法處理行。若是發生這種狀況,數據庫引擎將在查詢執行過程當中生成錯誤。經過使用 ROBUST PLAN,能夠指示查詢優化器不考慮可能會遇到該問題的全部查詢計劃。

若是不能使用這樣的計劃,查詢優化器將返回錯誤而不是延遲對查詢執行的錯誤檢測。行能夠包含可變長度列;數據庫引擎容許將行大小定義爲超過數據庫引擎處理能力的最大可能的大小。一般,應用程序存儲實際大小在數據庫引擎處理能力範圍內的行,而無論最大可能大小。若是數據庫引擎遇到過長的行,則返回執行錯誤。

USE PLAN N'xml_plan'

強制查詢優化器對查詢使用由 'xml_plan' 指定的現有查詢計劃。不能使用 INSERT、UPDATE、MERGE 或 DELETE 語句來指定 USE PLAN。

TABLE HINT (exposed_object_name [, <table_hint> [ [, ]...n] ])

將指定的表提示應用到與 exposed_object_name 對應的表或視圖。咱們建議僅在計劃指南的上下文中將表提示用做查詢提示。

exposed_object_name 能夠爲如下引用之一:

  • 當對查詢的 FROM 子句中的表或視圖使用別名時,exposed_object_name 就是別名。

  • 若是不使用別名,exposed_object_name 與 FROM 子句中引用的表或視圖徹底匹配。例如,若是使用由兩部分組成的名稱引用了表或視圖,則exposed_object_name 就是這個由兩部分組成的名稱。

若是指定了 exposed_object_name 但未指定表提示,則將忽略在查詢中指定爲對象表提示的一部分的任何索引,並由查詢優化器來決定索引的使用。當您沒法修改原始查詢時,可使用此方法來消除 INDEX 表提示的影響。請參閱示例 J。

<table_hint> ::= { [ NOEXPAND ] { INDEX ( index_value [ ,...n] ) | INDEX = (index_value ) | FORCESEEK [(index_value(index_column_name [,...])) ]| FORCESCAN | HOLDLOCK | NOLOCK | NOWAIT | PAGLOCK | READCOMMITTED | READCOMMITTEDLOCK | READPAST | READUNCOMMITTED | REPEATABLEREAD | ROWLOCK | SERIALIZABLE |SPATIAL_WINDOW_MAX_CELLS | TABLOCK | TABLOCKX | UPDLOCK | XLOCK }

要做爲查詢提示應用於與 exposed_object_name對應的表或視圖的表提示。有關這些提示的說明,請參閱表提示 (Transact-SQL)

不容許將非 INDEX、FORCESCAN 和 FORCESEEK 的表提示用做查詢提示,除非該查詢已經具備一個指定該表提示的 WITH 子句。有關詳細信息,請參閱備註。

注意事項注意

指定帶參數的 FORCESEEK 限制優化器能夠考慮的計劃數大於指定不帶參數的 FORCESEEK 時的計劃數。這可能致使在更多狀況下出現「沒法生成計劃」錯誤。在將來的版本中,對優化器進行內部修改後可容許考慮更多計劃。

只有在 INSERT 語句中使用了 SELECT 子句時,才能在該語句中指定查詢提示。

只能在頂級查詢中指定查詢提示,不能在子查詢指定。 將表提示指定爲查詢提示時,能夠在頂級查詢或子查詢中指定此提示,但爲 TABLE HINT 子句中的 exposed_object_name 指定的值必須與該查詢或子查詢中公開的名稱徹底匹配。

將表提示指定爲查詢提示

咱們建議僅在計劃指南的上下文中將 INDEX、FORCESCAN 或 FORCESEEK 表提示用做查詢提示。當您沒法修改原始查詢時(例如,因爲它是第三方應用程序),計劃指南將頗有用。計劃指南中指定的查詢提示在查詢編譯和優化前添加到查詢中。對於即席查詢,僅在測試計劃指南語句時才應使用 TABLE HINT 子句。對於全部其餘即席查詢,建議僅將這些提示指定爲表提示。

若是將 INDEX、FORCESCAN 和 FORCESEEK 表提示指定爲查詢提示,它們會對如下對象有效:

  • 視圖

  • 索引視圖

  • 公用表表達式(必須在其結果集填充公用表表達式的 SELECT 語句中指定提示)

  • 動態管理視圖

  • 命名子查詢

能夠爲沒有任何現有表提示的查詢指定 INDEX、FORCESCAN 和 FORCESEEK 表提示做爲查詢提示,這些提示也可用於分別替換查詢中的現有 INDEX、FORCESCAN 或 FORCESEEK 提示。不容許將非 INDEX、FORCESCAN 和 FORCESEEK 的表提示用做查詢提示,除非該查詢已經具備一個指定該表提示的 WITH 子句。這種狀況下,還必須使用 OPTION 子句中的 TABLE HINT 來將匹配的提示指定爲查詢提示,以保留查詢的語義。例如,若是查詢包含表提示 NOLOCK,則計劃指南的@hints 參數中的 OPTION 子句必須也包含 NOLOCK 提示。請參見示例 K。當經過使用 OPTION 子句中的 TABLE HINT 指定了非 INDEX、FORCESCAN 或 FORCESEEK 的表提示,而未指定匹配的查詢提示時,或指定了後者而未指定前者,則會引起錯誤 8702,表示 OPTION 子句會致使查詢的語義發生變化,該查詢將失敗。

 

  1. declare @a table (v varchar(100),vid int
  2.  
  3. insertinto @a 
  4. select'abc'as v,1 as vid 
  5. unionall 
  6. select'cde',123 
  7. unionall 
  8. select'cd',2  
  9. unionall 
  10. select'abc',12 
  11. unionall 
  12. select'def',123 
  13. unionall 
  14. select'cde',12 
  15. unionall 
  16. select'def',2 
  17. unionall 
  18. select'cde',1 
  19. unionall 
  20. select'cdef',1 
  21.  
  22.  
  23. --1.group 
  24. --1.1hash 
  25. select v, 
  26.        COUNT(vid) 
  27. from @a 
  28. groupby
  29. option(hash group)      
  30.  
  31. --1.2order 
  32. select v, 
  33.        COUNT(vid) 
  34. from @a 
  35. groupby
  36. option(ordergroup)  
  37.  
  38. --1.3能夠用在distinct中 
  39. selectdistinct *   
  40. from @a 
  41. option(ordergroup)  
  42.  
  43.  
  44.  
  45. --2.union 
  46. --2.1hash 
  47. select'abc'as v,1 as vid 
  48. union  
  49. select'cd',123 
  50. union 
  51. select'cd',2  
  52. union 
  53. select'abc',1 
  54. option(hash union)    
  55.  
  56. --2.2merge 
  57. select'abc'as v,1 as vid 
  58. union  
  59. select'cd',123 
  60. union 
  61. select'cd',2  
  62. union 
  63. select'abc',1 
  64. option(merge union)   
  65.  
  66. --2.3concat 
  67. select'abc'as v,1 as vid 
  68. union  
  69. select'cd',123 
  70. union 
  71. select'cd',2  
  72. union 
  73. select'abc',1 
  74. option(concat union)  
  75.   
  76.   
  77. --3.join 
  78. --3.1hash 
  79. select
  80. from 
  81. (  
  82.     select'abc'as v,1 as vid 
  83.     unionall 
  84.     select'cd',2 
  85. )a 
  86. innerjoin 
  87.     select'cd'as v,2 as vid 
  88.     unionall 
  89.     select'abc',1 
  90. )b 
  91. on a.vid = b.vid  
  92. option(hash join)    
  93.  
  94.  
  95. --3.2merge 
  96. select
  97. from 
  98. (  
  99.     select'abc'as v,1 as vid 
  100.     unionall 
  101.     select'cd',2 
  102. )a 
  103. innerjoin 
  104.     select'cd'as v,2 as vid 
  105.     unionall 
  106.     select'abc',1 
  107. )b 
  108. on a.vid = b.vid 
  109. option(merge join)    
  110.  
  111.  
  112. --3.3loop 
  113. select
  114. from 
  115. (  
  116.     select'abc'as v,1 as vid 
  117.     unionall 
  118.     select'cd',2 
  119. )a 
  120. innerjoin 
  121.     select'cd'as v,2 as vid 
  122.     unionall 
  123.     select'abc',1 
  124. )b 
  125. on a.vid = b.vid 
  126. option(loop join)  
  127.  
  128.  
  129.  
  130. --4.expand views 
  131. --建表 
  132. select * into wc_objects 
  133. from sys.objects  
  134.  
  135. --添加主鍵約束 
  136. altertable wc_objects 
  137. addconstraint pk_wc_objectid primarykey(object_id) 
  138.  
  139. --建立視圖 
  140. createview select_wc_objects 
  141. with schemabinding 
  142. as 
  143.  
  144. selectname
  145.        object_id, 
  146.        type, 
  147.        type_desc 
  148. from dbo.wc_objects 
  149. go 
  150.  
  151.  
  152. --建立惟一的彙集索引做爲視圖索引(也就是視圖對應的索引) 
  153. createunique clustered index uni_select_wc_objects 
  154. on select_wc_objects(object_id) 
  155.  
  156. --這裏會展開視圖,直接引用底層的原始表wc_objects 
  157. select
  158. from select_wc_objects 
  159.  
  160. --不會展開,直接使用惟一彙集索引uni_select_wc_objects中的數據 
  161. select
  162. from select_wc_objects with(noexpand) 
  163.  
  164.  
  165.  
  166. --5.fast n:對查詢進行優化,以便快速檢索前n行 
  167. select o.OrderDate, 
  168.        o.SalesOrderNumber 
  169. from sales.SalesOrderHeader o 
  170. innerjoin sales.SalesOrderDetail d 
  171.         on o.SalesOrderID =d.SalesOrderID  
  172. option(fast 100) --在返回前n行後,查詢繼續執行並生成完整的結果集 
  173.  
  174.  
  175.  
  176. --6.force order:通常不建議使用,應該由SQL Server來決定聯接順序 
  177. SELECT
  178. FROM sales.SalesOrderHeader o  
  179. INNERJOIN sales.SalesOrderDetail m 
  180.         ON O.salesorderid = m.salesorderid 
  181. innerjoin production.Product e 
  182.         on m.ProductID = e.ProductID 
  183. option(forceorder--用了這個致使查詢更慢 
  184.  
  185.  
  186. --7.keep plan:強制查詢優化器對查詢放寬估計的從新編譯閾值 
  187. SELECT
  188. FROM sales.SalesOrderHeader o  
  189. INNERJOIN sales.SalesOrderDetail m 
  190.         ON O.salesorderid = m.salesorderid 
  191. innerjoin production.Product e 
  192.         on m.ProductID = e.ProductID 
  193. option(keep plan) 
  194.  
  195.  
  196. --8.keepfixed plan:強制查詢優化器不因統計信息的更改而從新編譯查詢 
  197. --可確保只有更改基礎表的架構或在那些表上執行sp_recompile時才從新編譯查詢 
  198. SELECT
  199. FROM sales.SalesOrderHeader o  
  200. INNERJOIN sales.SalesOrderDetail m 
  201.         ON O.salesorderid = m.salesorderid 
  202. innerjoin production.Product e 
  203.         on m.ProductID = e.ProductID 
  204. option(keepfixed plan) 
  205.  
  206.  
  207.  
  208. /*================================= 
  209. 9.maxrecursion自動產生大量連續的數字 
  210. ==================================*/ 
  211. WITH t   
  212. AS 
  213. SELECT 1 AS
  214. UNIONALL 
  215. SELECT r+1  
  216. FROM
  217. WHERE r < 10000 
  218.  
  219. SELECT *  
  220. FROM
  221. OPTION(maxrecursion 10000)  --限制最大遞歸數字 
  222.  
  223.  
  224.  
  225. --10.MAXDOP 
  226. --對於指定了max degree of parallelism配置選項的查詢, 
  227. --會覆蓋sp_configure 和資源調控器的該選項 
  228. SELECT
  229. FROM sales.SalesOrderHeader o  
  230. INNERJOIN sales.SalesOrderDetail m 
  231.         ON O.salesorderid = m.salesorderid 
  232. innerjoin production.Product e 
  233.         on m.ProductID = e.ProductID 
  234. option(maxdop 2) 
  235.  
  236.  
  237.  
  238. --11.OPTIMIZE FOR 
  239. declare @name nvarchar(50)  
  240. declare @id int 
  241.  
  242. select @name ='a'
  243.        @id   =500 
  244.  
  245. SELECT
  246. FROM sales.SalesOrderHeader o  
  247. INNERJOIN sales.SalesOrderDetail m 
  248.         ON O.salesorderid = m.salesorderid 
  249. innerjoin production.Product e 
  250.         on m.ProductID = e.ProductID 
  251. where e.Namelike @name +'%'  
  252.       and e.ProductID >= @id  
  253. option(optimize for(@name='a',@id unknown)) 
  254.  
  255.  
  256.  
  257. --12.OPTIMIZE FOR UNKNOWN 
  258. declare @name1 nvarchar(50)  
  259. declare @id1 int 
  260.  
  261. select @name1 ='a'
  262.        @id1   =500; 
  263.  
  264. SELECT
  265. FROM sales.SalesOrderHeader o  
  266. INNERJOIN sales.SalesOrderDetail m 
  267.         ON O.salesorderid = m.salesorderid 
  268. innerjoin production.Product e 
  269.         on m.ProductID = e.ProductID 
  270. where e.Namelike @name1 +'%'  
  271.       and e.ProductID >= @id1  
  272. option(optimize for unknown)  
  273.  
  274.  
  275.  
  276. --12.use plan 
  277. createtable txt(id numeric(10,0) primarykey
  278.                  v varchar(20), 
  279.                  vv int
  280.  
  281. createindex txt_v on txt(v) 
  282.  
  283. insertinto txt 
  284. select object_id, 
  285.        type_desc, 
  286.        schema_id 
  287. from sys.objects 
  288. where LEN(type_desc) < 20 
  289.  
  290.  
  291. --取得xml格式的執行計劃 
  292. setstatistics xml on 
  293.  
  294. select *  
  295. from txt  
  296. where id > 1000 and 
  297.       vv > 2 
  298.  
  299. setstatistics xml off 
  300.  
  301. select
  302. from txt 
  303. option
  304. use plan 
  305. '<ShowPlanXML xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan"  
  306. Version="1.1" Build="10.50.1600.1"
  307. <BatchSequence><Batch><Statements> 
  308. <StmtSimple StatementText="SELECT * FROM [txt] WHERE [id]>@1 AND [vv]>@2"  
  309. StatementId="1" StatementCompId="1" StatementType="SELECT" StatementSubTreeCost="0.00429444"  
  310. StatementEstRows="42.2945" StatementOptmLevel="TRIVIAL" QueryHash="0xA4E0AA4B0A87F88B"  
  311. QueryPlanHash="0x3325250D8A42F500"
  312. <StatementSetOptions QUOTED_IDENTIFIER="true" ARITHABORT="true" CONCAT_NULL_YIELDS_NULL="true"  
  313. ANSI_NULLS="true" ANSI_PADDING="true" ANSI_WARNINGS="true" NUMERIC_ROUNDABORT="false"/> 
  314. <QueryPlan DegreeOfParallelism="1" CachedPlanSize="16" CompileTime="1" CompileCPU="1"  
  315. CompileMemory="136"><RelOp NodeId="0"  
  316. PhysicalOp="Clustered Index Seek" LogicalOp="Clustered Index Seek"  
  317. EstimateRows="42.2945" EstimateIO="0.00386574" EstimateCPU="0.0004287"  
  318. AvgRowSize="34" EstimatedTotalSubtreeCost="0.00429444"  
  319. TableCardinality="292" Parallel="0" EstimateRebinds="0" EstimateRewinds="0"
  320. <OutputList><ColumnReference Database="[test2]"  
  321. Schema="[dbo]"Table="[txt]"Column="id"/><ColumnReference  
  322. Database="[test2]"Schema="[dbo]"Table="[txt]"Column="v"/> 
  323. <ColumnReference Database="[test2]"Schema="[dbo]"Table="[txt]"Column="vv"/> 
  324. </OutputList><RunTimeInformation><RunTimeCountersPerThread Thread="0"  
  325. ActualRows="5" ActualEndOfScans="1" ActualExecutions="1"/> 
  326. </RunTimeInformation><IndexScan Ordered="1" ScanDirection="FORWARD"  
  327. ForcedIndex="0" ForceSeek="0" NoExpandHint="0"><DefinedValues> 
  328. <DefinedValue><ColumnReference Database="[test2]"  
  329. Schema="[dbo]"Table="[txt]"Column="id"/> 
  330. </DefinedValue><DefinedValue><ColumnReference  
  331. Database="[test2]"Schema="[dbo]"Table="[txt]"  
  332. Column="v"/></DefinedValue><DefinedValue> 
  333. <ColumnReference Database="[test2]"Schema="[dbo]"  
  334. Table="[txt]"Column="vv"/></DefinedValue></DefinedValues> 
  335. <Object Database="[test2]"Schema="[dbo]"Table="[txt]"  
  336. Index="[PK__txt__3213E83F4D1564AE]" IndexKind="Clustered"/> 
  337. <SeekPredicates><SeekPredicateNew><SeekKeys> 
  338. <StartRange ScanType="GT"><RangeColumns> 
  339. <ColumnReference Database="[test2]"Schema="[dbo]"Table="[txt]"  
  340. Column="id"/></RangeColumns><RangeExpressions><ScalarOperator  
  341. ScalarString="CONVERT_IMPLICIT(numeric(10,0),[@1],0)"><Identifier> 
  342. <ColumnReference Column="ConstExpr1003"><ScalarOperator> 
  343. <Convert DataType="numeric"Precision="10" Scale="0" Style="0" Implicit="1"
  344. <ScalarOperator><Identifier><ColumnReference Column="@1"/> 
  345. </Identifier></ScalarOperator></Convert></ScalarOperator> 
  346. </ColumnReference></Identifier></ScalarOperator> 
  347. </RangeExpressions></StartRange></SeekKeys></SeekPredicateNew> 
  348. </SeekPredicates><Predicate><ScalarOperator  
  349. ScalarString="[test2].[dbo].[txt].[vv]>CONVERT_IMPLICIT(int,[@2],0)"><Compare CompareOp="GT"
  350. <ScalarOperator><Identifier><ColumnReference Database="[test2]"Schema="[dbo]"  
  351. Table="[txt]"Column="vv"/></Identifier></ScalarOperator><ScalarOperator> 
  352. <Identifier><ColumnReference Column="ConstExpr1004"><ScalarOperator> 
  353. <Convert DataType="int" Style="0" Implicit="1"><ScalarOperator> 
  354. <Identifier><ColumnReference Column="@2"/></Identifier> 
  355. </ScalarOperator></Convert></ScalarOperator></ColumnReference> 
  356. </Identifier></ScalarOperator></Compare></ScalarOperator> 
  357. </Predicate></IndexScan></RelOp><ParameterList> 
  358. <ColumnReference Column="@2" ParameterCompiledValue="(2)" ParameterRuntimeValue="(2)"/> 
  359. <ColumnReference Column="@1" ParameterCompiledValue="(1000)"  
  360. ParameterRuntimeValue="(1000)"/></ParameterList></QueryPlan> 
  361. </StmtSimple></Statements></Batch></BatchSequence></ShowPlanXML>') 
  362.  
  363.  
  364.  
  365. --14.PARAMETERIZATION { SIMPLE | FORCED }  
  366. --PARAMETERIZATION查詢提示只能在計劃指南中指定,不能直接在查詢中指定該查詢提示 
  367. --14.1運行多條相似的查詢 
  368. select * from txt where id = 8 
  369.  
  370. select * from txt where id = 9 
  371.  
  372.  
  373. --14.2經過查詢緩存的計劃所對應的sql文本,發現不少都是相同的 
  374. --並且大部分的objtype都是proc,adhoc,prepared. 
  375. SELECT *  
  376. FROM SYS.dm_exec_cached_plans E 
  377. CROSS APPLY SYS.dm_exec_sql_text(E.plan_handle)EE 
  378. WHERE EE.text LIKE'%select * from txt where id =%' 
  379.  
  380.  
  381. declare @sqltext nvarchar(max
  382. declare @parameter nvarchar(max
  383.  
  384.  
  385. --14.3獲取查詢的參數化形式以及查詢的參數,放入變量中 
  386. exec sp_get_query_template  
  387.     @querytext = N'select * from txt where id = 8'
  388.     @templatetext= @sqltext output
  389.     @parameters = @parameter output 
  390.  
  391.  
  392. --14.4使用模板來建立計劃指南    
  393. exec sp_create_plan_guide 
  394.     @name = 'plan_guide_txt_template'
  395.     @stmt = @sqltext, 
  396.     @type = 'template',   
  397.     @module_or_batch = null
  398.     @params = @parameter, 
  399.     @hints = 'option(parameterization forced)'  
  400.      
  401.  
  402. --14.5再次查詢發現多條執行計劃已經變爲一條,usecounts計數增長 
  403. SELECT *  
  404. FROM SYS.dm_exec_cached_plans E 
  405. CROSS APPLY SYS.dm_exec_sql_text(E.plan_handle)EE 
  406. WHERE EE.text LIKE'%select * from txt where id =%' 
  407.  
  408.  
  409.  
  410. --15.ROBUST PLAN  
  411. --查詢優化器嘗試一個計劃,該計劃可能以性能爲代價得到最大可能的行大小 
  412. SELECT
  413. FROM sales.SalesOrderHeader o  
  414. INNERJOIN sales.SalesOrderDetail m 
  415.         ON O.salesorderid = m.salesorderid 
  416. innerjoin production.Product e 
  417.         on m.ProductID = e.ProductID 
  418. option(ROBUST PLAN) 
  419.  
  420.  
  421. --16.RECOMPILE  
  422. SELECT
  423. FROM sales.SalesOrderHeader o  
  424. INNERJOIN sales.SalesOrderDetail m 
  425.         ON O.salesorderid = m.salesorderid 
  426. innerjoin production.Product e 
  427.         on m.ProductID = e.ProductID 
  428. option(recompile) 
  429.  
  430. --若是是存儲過程,能夠經過下面的方式來顯式的從新編譯 
  431. exec 存儲過程名稱 with recompile 
declare @a table (v varchar(100),vid int)

insert into @a
select 'abc' as v,1 as vid
union all
select 'cde',123
union all
select 'cd',2 
union all
select 'abc',12
union all
select 'def',123
union all
select 'cde',12
union all
select 'def',2
union all
select 'cde',1
union all
select 'cdef',1


--1.group
--1.1hash
select v,
       COUNT(vid)
from @a
group by v
option(hash group)     

--1.2order
select v,
       COUNT(vid)
from @a
group by v
option(order group) 

--1.3能夠用在distinct中
select distinct *  
from @a
option(order group) 



--2.union
--2.1hash
select 'abc' as v,1 as vid
union 
select 'cd',123
union
select 'cd',2 
union
select 'abc',1
option(hash union)   

--2.2merge
select 'abc' as v,1 as vid
union 
select 'cd',123
union
select 'cd',2 
union
select 'abc',1
option(merge union)  

--2.3concat
select 'abc' as v,1 as vid
union 
select 'cd',123
union
select 'cd',2 
union
select 'abc',1
option(concat union) 
 
 
--3.join
--3.1hash
select *
from
( 
	select 'abc' as v,1 as vid
	union all
	select 'cd',2
)a
inner join
(
	select 'cd' as v,2 as vid
	union all
	select 'abc',1
)b
on a.vid = b.vid 
option(hash join)   


--3.2merge
select *
from
( 
	select 'abc' as v,1 as vid
	union all
	select 'cd',2
)a
inner join
(
	select 'cd' as v,2 as vid
	union all
	select 'abc',1
)b
on a.vid = b.vid
option(merge join)   


--3.3loop
select *
from
( 
	select 'abc' as v,1 as vid
	union all
	select 'cd',2
)a
inner join
(
	select 'cd' as v,2 as vid
	union all
	select 'abc',1
)b
on a.vid = b.vid
option(loop join) 



--4.expand views
--建表
select * into wc_objects
from sys.objects 

--添加主鍵約束
alter table wc_objects
add constraint pk_wc_objectid primary key(object_id)

--建立視圖
create view select_wc_objects
with schemabinding
as

select name,
       object_id,
       type,
       type_desc
from dbo.wc_objects
go


--建立惟一的彙集索引做爲視圖索引(也就是視圖對應的索引)
create unique clustered index uni_select_wc_objects
on select_wc_objects(object_id)

--這裏會展開視圖,直接引用底層的原始表wc_objects
select *
from select_wc_objects

--不會展開,直接使用惟一彙集索引uni_select_wc_objects中的數據
select *
from select_wc_objects with(noexpand)



--5.fast n:對查詢進行優化,以便快速檢索前n行
select o.OrderDate,
       o.SalesOrderNumber
from sales.SalesOrderHeader o
inner join sales.SalesOrderDetail d
        on o.SalesOrderID =d.SalesOrderID 
option(fast 100) --在返回前n行後,查詢繼續執行並生成完整的結果集



--6.force order:通常不建議使用,應該由SQL Server來決定聯接順序
SELECT *
FROM sales.SalesOrderHeader o 
INNER JOIN sales.SalesOrderDetail m
		ON O.salesorderid = m.salesorderid
inner join production.Product e
        on m.ProductID = e.ProductID
option(force order)  --用了這個致使查詢更慢


--7.keep plan:強制查詢優化器對查詢放寬估計的從新編譯閾值
SELECT *
FROM sales.SalesOrderHeader o 
INNER JOIN sales.SalesOrderDetail m
		ON O.salesorderid = m.salesorderid
inner join production.Product e
        on m.ProductID = e.ProductID
option(keep plan)


--8.keepfixed plan:強制查詢優化器不因統計信息的更改而從新編譯查詢
--可確保只有更改基礎表的架構或在那些表上執行sp_recompile時才從新編譯查詢
SELECT *
FROM sales.SalesOrderHeader o 
INNER JOIN sales.SalesOrderDetail m
		ON O.salesorderid = m.salesorderid
inner join production.Product e
        on m.ProductID = e.ProductID
option(keepfixed plan)



/*=================================
9.maxrecursion自動產生大量連續的數字
==================================*/
WITH t  
AS
(
SELECT 1 AS r
UNION ALL
SELECT r+1 
FROM t
WHERE r < 10000
)

SELECT * 
FROM t
OPTION(maxrecursion 10000)  --限制最大遞歸數字



--10.MAXDOP
--對於指定了max degree of parallelism配置選項的查詢,
--會覆蓋sp_configure 和資源調控器的該選項
SELECT *
FROM sales.SalesOrderHeader o 
INNER JOIN sales.SalesOrderDetail m
		ON O.salesorderid = m.salesorderid
inner join production.Product e
        on m.ProductID = e.ProductID
option(maxdop 2)



--11.OPTIMIZE FOR
declare @name nvarchar(50) 
declare @id int

select @name ='a',
       @id   =500

SELECT *
FROM sales.SalesOrderHeader o 
INNER JOIN sales.SalesOrderDetail m
		ON O.salesorderid = m.salesorderid
inner join production.Product e
        on m.ProductID = e.ProductID
where e.Name like @name +'%' 
      and e.ProductID >= @id 
option(optimize for(@name='a',@id unknown))



--12.OPTIMIZE FOR UNKNOWN
declare @name1 nvarchar(50) 
declare @id1 int

select @name1 ='a',
       @id1   =500;

SELECT *
FROM sales.SalesOrderHeader o 
INNER JOIN sales.SalesOrderDetail m
		ON O.salesorderid = m.salesorderid
inner join production.Product e
        on m.ProductID = e.ProductID
where e.Name like @name1 +'%' 
      and e.ProductID >= @id1 
option(optimize for unknown) 



--12.use plan
create table txt(id numeric(10,0) primary key,
                 v varchar(20),
                 vv int )

create index txt_v on txt(v)

insert into txt
select object_id,
       type_desc,
       schema_id
from sys.objects
where LEN(type_desc) < 20


--取得xml格式的執行計劃
set statistics xml on

select * 
from txt 
where id > 1000 and
	  vv > 2

set statistics xml off

select *
from txt
option(
use plan
'<ShowPlanXML xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan" 
Version="1.1" Build="10.50.1600.1">
<BatchSequence><Batch><Statements>
<StmtSimple StatementText="SELECT * FROM [txt] WHERE [id]>@1 AND [vv]>@2" 
StatementId="1" StatementCompId="1" StatementType="SELECT" StatementSubTreeCost="0.00429444" 
StatementEstRows="42.2945" StatementOptmLevel="TRIVIAL" QueryHash="0xA4E0AA4B0A87F88B" 
QueryPlanHash="0x3325250D8A42F500">
<StatementSetOptions QUOTED_IDENTIFIER="true" ARITHABORT="true" CONCAT_NULL_YIELDS_NULL="true" 
ANSI_NULLS="true" ANSI_PADDING="true" ANSI_WARNINGS="true" NUMERIC_ROUNDABORT="false"/>
<QueryPlan DegreeOfParallelism="1" CachedPlanSize="16" CompileTime="1" CompileCPU="1" 
CompileMemory="136"><RelOp NodeId="0" 
PhysicalOp="Clustered Index Seek" LogicalOp="Clustered Index Seek" 
EstimateRows="42.2945" EstimateIO="0.00386574" EstimateCPU="0.0004287" 
AvgRowSize="34" EstimatedTotalSubtreeCost="0.00429444" 
TableCardinality="292" Parallel="0" EstimateRebinds="0" EstimateRewinds="0">
<OutputList><ColumnReference Database="[test2]" 
Schema="[dbo]" Table="[txt]" Column="id"/><ColumnReference 
Database="[test2]" Schema="[dbo]" Table="[txt]" Column="v"/>
<ColumnReference Database="[test2]" Schema="[dbo]" Table="[txt]" Column="vv"/>
</OutputList><RunTimeInformation><RunTimeCountersPerThread Thread="0" 
ActualRows="5" ActualEndOfScans="1" ActualExecutions="1"/>
</RunTimeInformation><IndexScan Ordered="1" ScanDirection="FORWARD" 
ForcedIndex="0" ForceSeek="0" NoExpandHint="0"><DefinedValues>
<DefinedValue><ColumnReference Database="[test2]" 
Schema="[dbo]" Table="[txt]" Column="id"/>
</DefinedValue><DefinedValue><ColumnReference 
Database="[test2]" Schema="[dbo]" Table="[txt]" 
Column="v"/></DefinedValue><DefinedValue>
<ColumnReference Database="[test2]" Schema="[dbo]" 
Table="[txt]" Column="vv"/></DefinedValue></DefinedValues>
<Object Database="[test2]" Schema="[dbo]" Table="[txt]" 
Index="[PK__txt__3213E83F4D1564AE]" IndexKind="Clustered"/>
<SeekPredicates><SeekPredicateNew><SeekKeys>
<StartRange ScanType="GT"><RangeColumns>
<ColumnReference Database="[test2]" Schema="[dbo]" Table="[txt]" 
Column="id"/></RangeColumns><RangeExpressions><ScalarOperator 
ScalarString="CONVERT_IMPLICIT(numeric(10,0),[@1],0)"><Identifier>
<ColumnReference Column="ConstExpr1003"><ScalarOperator>
<Convert DataType="numeric" Precision="10" Scale="0" Style="0" Implicit="1">
<ScalarOperator><Identifier><ColumnReference Column="@1"/>
</Identifier></ScalarOperator></Convert></ScalarOperator>
</ColumnReference></Identifier></ScalarOperator>
</RangeExpressions></StartRange></SeekKeys></SeekPredicateNew>
</SeekPredicates><Predicate><ScalarOperator 
ScalarString="[test2].[dbo].[txt].[vv]>CONVERT_IMPLICIT(int,[@2],0)"><Compare CompareOp="GT">
<ScalarOperator><Identifier><ColumnReference Database="[test2]" Schema="[dbo]" 
Table="[txt]" Column="vv"/></Identifier></ScalarOperator><ScalarOperator>
<Identifier><ColumnReference Column="ConstExpr1004"><ScalarOperator>
<Convert DataType="int" Style="0" Implicit="1"><ScalarOperator>
<Identifier><ColumnReference Column="@2"/></Identifier>
</ScalarOperator></Convert></ScalarOperator></ColumnReference>
</Identifier></ScalarOperator></Compare></ScalarOperator>
</Predicate></IndexScan></RelOp><ParameterList>
<ColumnReference Column="@2" ParameterCompiledValue="(2)" ParameterRuntimeValue="(2)"/>
<ColumnReference Column="@1" ParameterCompiledValue="(1000)" 
ParameterRuntimeValue="(1000)"/></ParameterList></QueryPlan>
</StmtSimple></Statements></Batch></BatchSequence></ShowPlanXML>')



--14.PARAMETERIZATION { SIMPLE | FORCED } 
--PARAMETERIZATION查詢提示只能在計劃指南中指定,不能直接在查詢中指定該查詢提示
--14.1運行多條相似的查詢
select * from txt where id = 8

select * from txt where id = 9


--14.2經過查詢緩存的計劃所對應的sql文本,發現不少都是相同的
--並且大部分的objtype都是proc,adhoc,prepared.
SELECT * 
FROM SYS.dm_exec_cached_plans E
CROSS APPLY SYS.dm_exec_sql_text(E.plan_handle)EE
WHERE EE.text LIKE '%select * from txt where id =%'


declare @sqltext nvarchar(max)
declare @parameter nvarchar(max)


--14.3獲取查詢的參數化形式以及查詢的參數,放入變量中
exec sp_get_query_template 
	@querytext = N'select * from txt where id = 8',
	@templatetext= @sqltext output,
	@parameters = @parameter output


--14.4使用模板來建立計劃指南	
exec sp_create_plan_guide
	@name = 'plan_guide_txt_template',
	@stmt = @sqltext,
	@type = 'template',  
	@module_or_batch = null,
	@params = @parameter,
	@hints = 'option(parameterization forced)' 
	

--14.5再次查詢發現多條執行計劃已經變爲一條,usecounts計數增長
SELECT * 
FROM SYS.dm_exec_cached_plans E
CROSS APPLY SYS.dm_exec_sql_text(E.plan_handle)EE
WHERE EE.text LIKE '%select * from txt where id =%'



--15.ROBUST PLAN 
--查詢優化器嘗試一個計劃,該計劃可能以性能爲代價得到最大可能的行大小
SELECT *
FROM sales.SalesOrderHeader o 
INNER JOIN sales.SalesOrderDetail m
		ON O.salesorderid = m.salesorderid
inner join production.Product e
        on m.ProductID = e.ProductID
option(ROBUST PLAN)


--16.RECOMPILE 
SELECT *
FROM sales.SalesOrderHeader o 
INNER JOIN sales.SalesOrderDetail m
		ON O.salesorderid = m.salesorderid
inner join production.Product e
        on m.ProductID = e.ProductID
option(recompile)

--若是是存儲過程,能夠經過下面的方式來顯式的從新編譯
exec 存儲過程名稱 with recompile

 

表提示的參數

WITH ( <table_hint> ) [ [, ]...n]

存在一些例外狀況:只有在使用 WITH 關鍵字指定表提示時,才支持在 FROM 子句中使用這些提示。指定表提示時必須使用括號。

重要說明重要提示

不推薦省略 WITH 關鍵字:後續版本的 Microsoft SQL Server 將刪除該功能。請避免在新的開發工做中使用該功能,並着手修改當前還在使用該功能的應用程序。

使用或不使用 WITH 關鍵字都可使用的表提示以下:NOLOCK, READUNCOMMITTED、UPDLOCK、REPEATABLEREAD、SERIALIZABLE、READCOMMITTED、TABLOCK、TABLOCKX、PAGLOCK、ROWLOCK、NOWAIT、READPAST、XLOCK 和 NOEXPAND。若是指定的表提示不含 WITH 關鍵字,則必須單獨指定該提示。 例如:

 
複製
FROM t (TABLOCK)

若是指定的提示含其餘選項,則指定的提示必須含 WITH 關鍵字:

 
複製
FROM t WITH (TABLOCK, INDEX(myindex))

建議在表提示之間使用逗號。

重要說明重要提示

不推薦用空格而不是逗號分隔提示:後續版本的 Microsoft SQL Server 將刪除該功能。請不要在新的開發工做中使用該功能,並儘快修改當前還在使用該功能的應用程序。

在針對兼容級別爲 90 及更高的數據庫的查詢中使用提示時,即存在這些限制。

NOEXPAND

指定查詢優化器處理查詢時,不擴展任何索引視圖來訪問基礎表。 查詢優化器將視圖當成包含彙集索引的表處理。 NOEXPAND 僅適用於索引視圖。有關詳細信息,請參閱備註。

INDEX (index_value [,... n] ) | INDEX = (index_value)

INDEX() 語法指定供查詢優化器在處理該語句時使用的一個或多個索引的名稱或 ID。另外一供選擇的 INDEX = 語法指定單個索引值。只能爲每一個表指定一個索引提示。

若是存在彙集索引,則 INDEX(0) 強制執行彙集索引掃描,INDEX(1) 強制執行彙集索引掃描或查找。若是不存在彙集索引,則 INDEX(0) 強制執行表掃描,INDEX(1) 被解釋爲錯誤。

若是在單個提示列表中使用了多個索引,則會忽略重複項,其他列出的索引將用於檢索表中的行。索引提示中的索引順序很重要。多索引提示還強制執行索引 AND 運算,查詢優化器將對所訪問的每一個索引應用盡量多的條件。若是提示索引的集合並未包含查詢引用的全部列,則會在 SQL Server 數據庫引擎檢索全部索引列後執行提取操做以檢索其他列。

注意注意

若是將引用多個索引的索引提示用於星型聯接中的事實數據表,則優化器將忽略索引提示,並返回一個警告消息。另外,不容許對包含指定索引提示的表執行索引 OR 操做。

表提示中的最大索引數爲 250 個非彙集索引。

KEEPIDENTITY

只適用於 INSERT 語句(當 BULK 選項與 OPENROWSET 一塊兒使用時)。

指定導入數據文件中的標識值用於標識列。 若是不指定 KEEPIDENTITY,則將驗證但不導入此列的標識值。查詢優化器將根據建立表時指定的種子值和增量值自動分配惟一值。

重要說明重要提示

若是數據文件不包含表或視圖中的標識列的值,而且標識列不是表中的最後一列,則必須跳過標識列。有關詳細信息,請參閱使用格式化文件跳過數據字段 (SQL Server)若是成功跳過了一個標識列,則查詢優化器自動將標識列的惟一值分配到導入的錶行中。

有關在 INSERT ... SELECT * FROM OPENROWSET(BULK...) 語句中使用此提示的示例,請參閱大容量導入數據時保留標識值 (SQL Server)

有關檢查表的標識值的信息,請參閱 DBCC CHECKIDENT (Transact-SQL)

KEEPDEFAULTS

只適用於 INSERT 語句(當 BULK 選項與 OPENROWSET 一塊兒使用時)。

指定數據記錄在某一表列缺乏值時插入此列的默認值(若是有),而不是插入 NULL。

有關在 INSERT ... SELECT * FROM OPENROWSET(BULK...) 語句中使用此提示的示例,請參閱在大容量導入期間保留空值或使用默認值 (SQL Server)

FORCESEEK [ (index_value(index_column_name [,...n ])) ]

指定查詢優化器僅使用索引查找操做做爲表或視圖中的數據的訪問途徑。 從 SQL Server 2008 R2 SP1 開始,還能夠指定索引參數。 在這種狀況下,查詢優化器僅考慮經過指定的索引(至少使用指定的索引列)執行索引查找操做。

index_value

是索引名稱或索引 ID 值。 不能指定索引 ID 0(堆)。 若要返回索引名稱或 ID,請查詢 sys.indexes 目錄視圖。

index_column_name

是要包含在查找操做中的索引列的名稱。 指定帶索引參數的 FORCESEEK 相似於將 FORCESEEK 與 INDEX 提示一塊兒使用。 可是,您能夠經過指定要查找的索引和查找操做中要考慮的索引列,更好地控制查詢優化器使用的訪問路徑。 該優化器能夠根據須要考慮其餘列。 例如,若是指定非彙集索引,優化器除了使用指定的列以外,還能夠選擇使用匯集索引鍵列。

能夠經過如下方式指定 FORCESEEK 提示。

 

語法

示例

說明

沒有索引或 INDEX 提示

FROM dbo.MyTable WITH (FORCESEEK)

查詢優化器僅考慮執行索引查找操做以經過任意相關索引訪問表或視圖。

與 INDEX 提示組合使用

FROM dbo.MyTable WITH (FORCESEEK, INDEX (MyIndex))

查詢優化器僅考慮執行索引查找操做以經過指定的索引訪問表或視圖。

經過指定索引和索引列進行參數化

FROM dbo.MyTable WITH (FORCESEEK (MyIndex (col1, col2, col3)))

查詢優化器僅考慮執行索引查找操做,以經過指定的索引(至少使用指定的索引列)訪問表或視圖。

使用 FORCESEEK 提示(具備或不帶索引參數)時,考慮如下準則。

  • 該提示能夠指定爲表提示或查詢提示。 有關查詢提示的詳細信息,請參閱查詢提示 (Transact-SQL)

  • 若要將 FORCESEEK 應用到索引視圖,還必須指定 NOEXPAND 提示。

  • 對每一個表或視圖最多應用該提示一次。

  • 不能爲遠程數據源指定該提示。 帶索引提示指定 FORCESEEK 時,將返回錯誤 7377;不帶索引提示使用 FORCESEEK 時,將返回錯誤 8180。

  • 若是 FORCESEEK 致使找不到計劃,將返回錯誤 8622。

使用索引參數指定 FORCESEEK 時,遵循如下準則和限制。

  • 該提示不能與 INDEX 提示或另外一個 FORCESEEK 提示一塊兒指定。

  • 至少必須指定一個列且該列爲第一個鍵列。

  • 能夠指定其餘索引列,可是不能跳過鍵列。 例如,若是指定的索引包含鍵列 abc,則有效的語法應包含 FORCESEEK (MyIndex (a))FORCESEEK (MyIndex (a, b) 無效的語法應包含FORCESEEK (MyIndex (c))FORCESEEK (MyIndex (a, c)

  • 在提示中指定的列名順序必須與引用的索引中列的順序匹配。

  • 不能指定不在索引鍵定義中的列。 例如,在非彙集索引中,只能指定定義的索引鍵列。 不能指定自動包含在索引中的彙集鍵列,可是優化器可使用這些列。

  • xVelocity 內存優化的列存儲索引不能做爲索引參數指定。 返回錯誤 366。

  • 修改索引定義(例如經過添加或刪除列)可能須要修改引用該索引的查詢。

  • 該提示阻止優化器考慮表的任何空間或 XML 索引。

  • 該提示不能與 FORCESCAN 提示一塊兒指定。

  • 對於分區的索引,不能在 FORCESEEK 提示中指定 SQL Server 隱式添加的分區列。

注意事項注意

指定帶參數的 FORCESEEK 限制優化器能夠考慮的計劃數大於指定不帶參數的 FORCESEEK 時的計劃數。這可能致使在更多狀況下出現「沒法生成計劃」錯誤。在將來的版本中,對優化器進行內部修改後可容許考慮更多計劃。

FORCESCAN

此提示在 SQL Server 2008 R2 SP1 中引入,它指定查詢優化器僅將索引掃描操做做爲引用的表或視圖的訪問路徑。對於優化器低估受影響的行數並選擇一個查找操做而非掃描操做的查詢,FORCESCAN 提示頗有用。出現這樣的狀況時,授予該操做的內存量過小,查詢性能將受影響。

指定 FORCESCAN 時有無 INDEX 提示都可。 與索引提示組合使用 (INDEX = index_name, FORCESCAN) 時,查詢優化器在訪問引用的表時僅考慮經過指定的索引掃描訪問路徑。能夠帶索引提示 INDEX(0) 指定 FORCESCAN,以強制對基表執行表掃描操做。

對於分區的表和索引,在經過查詢謂詞評估消除分區後應用 FORCESCAN。這意味着掃描僅適用於剩餘分區而非整個表。

FORCESCAN 提示存在如下限制。

  • 不能爲做爲 INSERT、UPDATE 或 DELETE 語句的目標的表指定該提示。

  • 該提示不能與一個以上的索引提示一塊兒使用。

  • 該提示阻止優化器考慮表的任何空間或 XML 索引。

  • 不能爲遠程數據源指定該提示。

  • 該提示不能與 FORCESEEK 提示一塊兒指定。

HOLDLOCK

等同於 SERIALIZABLE。 有關詳細信息,請參閱本主題後面的 SERIALIZABLE。 HOLDLOCK 僅應用於那些爲其指定了 HOLDLOCK 的表或視圖,而且僅在使用了 HOLDLOCK 的語句定義的事務的持續時間內應用。HOLDLOCK 不能被用於包含 FOR BROWSE 選項的 SELECT 語句。

IGNORE_CONSTRAINTS

只適用於 INSERT 語句(當 BULK 選項與 OPENROWSET 一塊兒使用時)。

指定大容量導入操做將忽略對錶的任何約束。 默認狀況下,INSERT 將檢查惟一約束和 CHECK 約束主鍵和外鍵約束當爲大容量導入操做指定 IGNORE_CONSTRAINTS 時,INSERT 必須忽略對目標表的這些約束。注意,您沒法禁用 UNIQUE、PRIMARY KEY 或 NOT NULL 約束。

若是輸入數據包含違反約束的行,則您可能但願禁用 CHECK 和 FOREIGN KEY 約束。經過禁用 CHECK 和 FOREIGN KEY 約束,能夠導入數據,而後使用 Transact-SQL 語句清除該數據。

不過,若是忽略了 CHECK 和 FOREIGN KEY 約束,在執行操做後,表上的每一個忽略的約束將在sys.check_constraintssys.foreign_keys 目錄視圖中標記爲is_not_trusted在某一時刻,應該檢查全表約束。若是在大容量導入操做以前表不爲空,則從新驗證約束的開銷可能超過對增量數據應用 CHECK 和 FOREIGN KEY 約束的開銷。

IGNORE_TRIGGERS

只適用於 INSERT 語句(當 BULK 選項與 OPENROWSET 一塊兒使用時)。

指定大容量導入操做將忽略爲表定義的全部觸發器。 默認狀況下,INSERT 將應用觸發器。

僅當應用程序不依賴任何觸發器,而且必須最大程度地提升性能時,才使用 IGNORE_TRIGGERS。

NOLOCK

等同於 READUNCOMMITTED。 有關詳細信息,請參閱本主題後面的 READUNCOMMITTED。

注意注意

對於 UPDATE 或 DELETE 語句:後續版本的 Microsoft SQL Server 將刪除該功能。請避免在新的開發工做中使用該功能,並着手修改當前還在使用該功能的應用程序。

NOWAIT

指示數據庫引擎在遇到表的鎖時,當即返回一條消息。 NOWAIT 等同於將特定表的 SET LOCK_TIMEOUT 值指定爲 0。

PAGLOCK

在一般行或鍵採用單個鎖的地方,或者一般採用單個表鎖的地方,請採用頁鎖。 默認狀況下,請使用與操做相對應的鎖模式。 在從 SNAPSHOT 隔離級別操做的事務中指定時,除非將 PAGLOCK 與須要鎖的其餘表提示(例如,UPDLOCK 和 HOLDLOCK)組合,不然不會取得頁鎖。

READCOMMITTED

指定讀操做使用鎖定或行版本控制來遵循有關 READ COMMITTED 隔離級別的規則。若是數據庫選項 READ_COMMITTED_SNAPSHOT 爲 OFF,數據庫引擎將在讀取數據時獲取共享鎖,在讀操做完成後釋放這些鎖。若是數據庫選項 READ_COMMITTED_SNAPSHOT 爲 ON,則數據庫引擎不獲取鎖,並使用行版本控制。有關隔離級別的詳細信息,請參閱SET TRANSACTION ISOLATION LEVEL (Transact-SQL)

注意注意

對於 UPDATE 或 DELETE 語句:後續版本的 Microsoft SQL Server 將刪除該功能。請避免在新的開發工做中使用該功能,並着手修改當前還在使用該功能的應用程序。

READCOMMITTEDLOCK

指定讀操做使用鎖定來遵循有關 READ COMMITTED 隔離級別的規則。不管 READ_COMMITTED_SNAPSHOT 數據庫選項的設置如何,數據庫引擎都將在讀取數據時獲取共享鎖,在讀操做完成後釋放這些鎖。有關隔離級別的詳細信息,請參閱SET TRANSACTION ISOLATION LEVEL (Transact-SQL)不能對 INSERT 語句的目標表指定此提示;將返回錯誤 4140。

READPAST

指定數據庫引擎不讀取由其餘事務鎖定的行。 若是指定了 READPAST,將跳過行級鎖。 也就是說,數據庫引擎將跳過這些行,而不是阻塞當前事務直到鎖被釋放。例如,假設表T1 包含一個單精度整數列,其值爲 一、二、三、4 和 5。若是事務 A 將值 3 更改成 8,但還沒有提交,則 SELECT * FROM T1 (READPAST) 將生成值 一、二、4 和 5。使用 SQL Server 表實現工做隊列時,READPAST 主要用於減小鎖定爭用。使用 READPAST 的隊列讀取器會跳過被其餘事務鎖定的隊列項,跳至下一個可用的隊列項,而不是等待其餘事務釋放鎖。

可爲 UPDATE 或 DELETE 語句中以及 FROM 子句中引用的任何表指定 READPAST。若是 READPAST 是在 UPDATE 語句中指定的,則僅當讀取數據以標識要更新的記錄時才應用 READPAST,而不考慮語句中指定 READPAST 的位置。不能爲 INSERT 語句的 INTO 子句中的表指定 READPAST。 使用 READPAST 的讀操做不會發生阻塞。讀取外鍵或索引視圖或者修改輔助索引時,使用 READPAST 的更新或刪除操做可能發生阻塞。

僅可在運行於 READ COMMITTED 或 REPEATABLE READ 隔離級別的事務中指定 READPAST。在從 SNAPSHOT 隔離級別操做的事務中指定時,READPAST 必須與須要鎖的其餘表提示(例如,UPDLOCK 和 HOLDLOCK)組合。

當 READ_COMMITTED_SNAPSHOT 數據庫選項設置爲 ON 而且知足如下條件之一時,沒法指定 READPAST 表提示。

  • 會話的事務隔離級別爲 READ COMMITTED。

  • 查詢中也指定了 READCOMMITTED 表提示。

若要在上述狀況下指定 READPAST 提示,請刪除 READCOMMITTED 表提示(若是存在),而後在查詢中包括 READCOMMITTEDLOCK 表提示。

READUNCOMMITTED

指定容許髒讀。 不發佈共享鎖來阻止其餘事務修改當前事務讀取的數據,其餘事務設置的排他鎖不會阻礙當前事務讀取鎖定數據。 容許髒讀可能產生較多的併發操做,但其代價是讀取之後會被其餘事務回滾的數據修改。 這可能會使您的事務出錯,向用戶顯示從未提交過的數據,或者致使用戶兩次看到記錄(或根本看不到記錄)。

READUNCOMMITTED 和 NOLOCK 提示僅適用於數據鎖。 全部查詢(包括那些帶有 READUNCOMMITTED 和 NOLOCK 提示的查詢)都會在編譯和執行過程當中獲取 Sch-S(架構穩定性)鎖。 所以,當併發事務持有表的 Sch-M(架構修改)鎖時,將阻塞查詢。 例如,數據定義語言 (DDL) 操做在修改表的架構信息以前獲取 Sch-M 鎖。全部併發查詢(包括那些使用 READUNCOMMITTED 或 NOLOCK 提示運行的查詢)都會在嘗試獲取 Sch-S 鎖時被阻塞。相反,持有 Sch-S 鎖的查詢將阻塞嘗試獲取 Sch-M 鎖的併發事務。

不能爲經過插入、更新或刪除操做修改過的表指定 READUNCOMMITTED 和 NOLOCK。SQL Server 查詢優化器忽略 FROM 子句中應用於 UPDATE 或 DELETE 語句的目標表的 READUNCOMMITTED 和 NOLOCK 提示。

注意注意

在 SQL Server 的將來版本中,將再也不支持在 FROM 子句中使用應用於 UPDATE 或 DELETE 語句目標表的 READUNCOMMITTED 和 NOLOCK 提示。請避免在新的開發工做上下文中使用這些提示,並計劃修改當前使用它們的應用程序。

能夠經過使用如下任意一種方法,在保護事務避免對未提交的數據修改進行髒讀的同時最大程度地減小鎖爭用:

  • READ COMMITTED 隔離級別,其中 READ_COMMITTED_SNAPSHOT 數據庫選項設置爲 ON。

  • SNAPSHOT 隔離級別。

有關隔離級別的詳細信息,請參閱 SET TRANSACTION ISOLATION LEVEL (Transact-SQL)

注意注意

若是在指定了 READUNCOMMITTED 的狀況下收到 601 號錯誤消息,則按解決死鎖錯誤 (1205) 的方法解決該錯誤,而後重試語句。

REPEATABLEREAD

指定事務在 REPEATABLE READ 隔離級別運行時,使用相同的鎖定語義執行一次掃描。有關隔離級別的詳細信息,請參閱SET TRANSACTION ISOLATION LEVEL (Transact-SQL)

ROWLOCK

指定一般採用頁鎖或表鎖時,採用行鎖。 若是在 SNAPSHOT 隔離級別運行的事務中指定了行鎖,除非將 ROWLOCK 與須要鎖的其餘表提示(例如,UPDLOCK 和 HOLDLOCK)組合使用,不然不會採用行鎖。

SPATIAL_WINDOW_MAX_CELLS = integer

指定在分割 geometry 或 geography 對象時使用的最大單元格數。number 是 1 到 8192 之間的值。

經過使用此選項,能夠在主要和輔助篩選器執行時間之間權衡性能以微調查詢執行時間。較大的數字將減小輔助篩選器執行時間,但會增長主要篩選器執行時間,而較小的數字恰相反。對於較密的空間數據,較大的數字經過爲主要篩選器提供更好的近似值並減小輔助篩選器執行時間,從而縮短了執行時間。對於較稀疏的數據,較小的數字將減小主要篩選器執行時間。

此選項適用於手動和自動網格分割。

SERIALIZABLE

等同於 HOLDLOCK。 經過將共享鎖一直保持到事務完成,使共享鎖具備更大的限制性;而不是在再也不須要所需的表或數據頁時當即釋放共享鎖,而不管事務是否完成。 執行掃描時所用的語義與在 SERIALIZABLE 隔離級別運行的事務的語義相同。 有關隔離級別的詳細信息,請參閱 SET TRANSACTION ISOLATION LEVEL (Transact-SQL)

TABLOCK

指定在表級別應用獲取的鎖。 獲取的鎖類型取決於正在執行的語句。 例如,SELECT 語句可能獲取一個共享鎖。經過指定 TABLOCK,將該共享鎖應用到整個表而非在行或頁級別應用。若是同時指定了 HOLDLOCK,則會一直持有表鎖,直至事務結束。

在經過使用 INSERT INTO <target_table> SELECT <columns> FROM <source_table> 語句將數據導入某一堆時,可經過爲目標表指定 TABLOCK 提示,實現語句的優化的日誌記錄和鎖定。此外,數據庫的恢復模式必須設置爲簡單或大容量日誌模式。有關詳細信息,請參閱INSERT (Transact-SQL)

在與 OPENROWSET 大容量行集提供程序一塊兒使用以將數據導入表的時候,TABLOCK 將啓用多個客戶端,以併發方式將數據加載到具備優化日誌記錄和鎖定的目標表中。有關詳細信息,請參閱在大容量導入中按最小方式記錄日誌的前提條件

TABLOCKX

指定對錶採用排他鎖。

UPDLOCK

指定採用更新鎖並保持到事務完成。 UPDLOCK 僅對行級別或頁級別的讀操做採用更新鎖。 若是將 UPDLOCK 與 TABLOCK 組合使用或出於一些其餘緣由採用表級鎖,將採用排他 (X) 鎖。

指定 UPDLOCK 時,忽略 READCOMMITTED 和 READCOMMITTEDLOCK 隔離級別提示。例如,若是將會話的隔離級別設置爲 SERIALIZABLE 且查詢指定 (UPDLOCK, READCOMMITTED),則忽略 READCOMMITTED 提示且使用 SERIALIZABLE 隔離級別運行事務。

XLOCK

指定採用排他鎖並保持到事務完成。 若是同時指定了 ROWLOCK, PAGLOCK 或 TABLOCK,則排他鎖將應用於相應的粒度級別。

 

若是查詢計劃不訪問表,則將忽略表提示。 這多是因爲優化器選擇了徹底不訪問該表,也多是由於改爲了訪問索引視圖。 在後一種狀況中,使用 OPTION (EXPAND VIEWS) 查詢提示可阻止訪問索引視圖。

全部鎖提示將傳播到查詢計劃訪問的全部表和視圖,其中包括在視圖中引用的表和視圖。另外,SQL Server 還將執行對應的鎖一致性檢查。

獲取行級別鎖的鎖提示 ROWLOCK、UPDLOCK 和 XLOCK 可能對索引鍵而不是實際的數據行採用鎖。例如,若是表具備非彙集索引,並且由涵蓋索引處理使用鎖提示的 SELECT 語句,則得到的鎖針對的是涵蓋索引中的索引鍵,而不是基表中的數據行。

若是表包含計算列,而該計算列是由訪問其餘表中的列的表達式或函數計算的,則不在這些表中使用表提示,而且不會傳播這些提示。例如,在查詢的表中指定 NOLOCK 表提示。此表包含的計算列是由訪問另外一表中的列的表達式和函數組合計算的。表達式和函數引用的表在被訪問時將不使用 NOLOCK 表提示。

對於 FROM 子句中的每一個表,SQL Server 不容許存在多個來自如下各個組的表提示:

  • 粒度提示:PAGLOCK、NOLOCK、READCOMMITTEDLOCK、ROWLOCK、TABLOCK 或 TABLOCKX。

  • 隔離級別提示:HOLDLOCK、NOLOCK、READCOMMITTED、REPEATABLEREAD 和 SERIALIZABLE。

篩選索引提示

篩選索引可用做表提示,但若是未涵蓋查詢選擇的全部行,則會致使查詢優化器產生錯誤 8622。下面是一個無效篩選索引提示的示例。該示例建立了篩選索引FIBillOfMaterialsWithComponentID,而後將其用做 SELECT 語句的索引提示。篩選索引謂詞包含 ComponentID 爲 53三、324 和 753 的數據行。查詢謂詞也包含 ComponentID 爲 53三、324 和 753 的數據行,但它擴展告終果集,使之包含 ComponentID 爲 855 和 924 的數據行,而篩選索引中則不包含這兩行。所以,查詢優化器沒法使用此篩選索引提示,併產生錯誤 8622。有關詳細信息,請參閱建立篩選索引

 
複製
USE AdventureWorks2012;
GO
IF EXISTS (SELECT name FROM sys.indexes
    WHERE name = N'FIBillOfMaterialsWithComponentID' 
    AND object_id = OBJECT_ID(N'Production.BillOfMaterials'))
DROP INDEX FIBillOfMaterialsWithComponentID
    ON Production.BillOfMaterials;
GO
CREATE NONCLUSTERED INDEX "FIBillOfMaterialsWithComponentID"
    ON Production.BillOfMaterials (ComponentID, StartDate, EndDate)
    WHERE ComponentID IN (533, 324, 753);
GO
SELECT StartDate, ComponentID FROM Production.BillOfMaterials
    WITH( INDEX (FIBillOfMaterialsWithComponentID) )
    WHERE ComponentID in (533, 324, 753, 855, 924);
GO

若是 SET 選項不包含篩選索引所需的值,查詢優化器將不考慮使用索引提示。有關詳細信息,請參閱CREATE INDEX (Transact-SQL)

使用 NOEXPAND

NOEXPAND 僅適用於索引視圖索引視圖是包含爲其建立的惟一彙集索引的視圖。若是查詢包含對同時存在於索引視圖和基表中的列的引用,並且查詢優化器肯定執行查詢的最佳方法是使用索引視圖,則查詢優化器將對視圖使用索引。此功能稱爲「索引視圖匹配」。僅在特定版本的 SQL Server 中支持查詢優化器自動使用索引視圖。有關 SQL Server 的版本支持的功能的列表,請參閱SQL Server 2012 各個版本支持的功能 (http://go.microsoft.com/fwlink/?linkid=232473)。

可是,爲了使優化器考慮使用索引視圖進行匹配,或者使用經過 NOEXPAND 提示引用的索引視圖,則必須將如下 SET 選項設置爲 ON。

 

ANSI_NULLS

ANSI_WARNINGS

CONCAT_NULL_YIELDS_NULL

ANSI_PADDING

ARITHABORT1

QUOTED_IDENTIFIERS

1 若是 ANSI_WARNINGS 設置爲 ON,則 ARITHABORT 將隱式設置爲 ON。所以,沒必要手動調整此設置。

另外,必須將 NUMERIC_ROUNDABORT 選項設置爲 OFF。

若要強制優化器對索引視圖使用索引,請指定 NOEXPAND 選項。 僅當查詢中也命名了此視圖時才能使用此提示。 若是某個查詢沒有在 FROM 子句中直接命名特定索引視圖,則 SQL Server 不提供用於在此查詢中強制使用此視圖的提示;可是,即便查詢中未直接引用索引視圖,查詢優化器仍會考慮使用索引視圖。

將表提示用做查詢提示

也可使用 OPTION (TABLE HINT) 子句將表提示指定爲查詢提示。咱們建議僅在計劃指南的上下文中將表提示用做查詢提示。對於即席查詢,請將這些提示僅指定爲表提示。有關詳細信息,請參閱查詢提示 (Transact-SQL)

KEEPIDENTITY、IGNORE_CONSTRAINTS 和 IGNORE_TRIGGERS 提示須要具備對錶的 ALTER 權限。

 

 

  1. --1.index 
  2. SELECT *   
  3. FROM sales.SalesOrderHeader o with(index(PK_SalesOrderHeader_SalesOrderID))  
  4. INNERJOIN sales.SalesOrderDetail m with(index(0))  --彙集索引掃描 
  5.         ON O.salesorderid = m.salesorderid   
  6. innerjoin production.Product e  with (index(1))    --彙集索引掃描或查找 
  7.         on m.ProductID = e.ProductID   
  8.  
  9.  
  10.  
  11. --2.KEEPIDENTITY  
  12. --建表 
  13. createtable dbo.y(yearvarchar(4) primarykey
  14.  
  15. insertinto dbo.y 
  16. values('2010'), 
  17.       ('2011'
  18.  
  19. CREATETABLE dbo.CALENDAR 
  20.     ( 
  21.     ID            NUMERIC (10)  identity(1,1) NOTNULL
  22.     YEAR          VARCHAR (4) NULL  referencesforeignkey y(year), 
  23.     QUARTER       VARCHAR (1) NULLdefault datename(quarter,getdate()), 
  24.     MONTH         VARCHAR (2) NULL
  25.     WEEK          VARCHAR (2) NULL
  26.     WEEK_MONTH    VARCHAR (2) NULL
  27.     WORK_DAY      BITNULL
  28.     IS_HOLIDAY    BITNULL
  29.     CONSTRAINT PK_CALENDAR PRIMARYKEY (ID) 
  30.     ) 
  31.      
  32. insertinto dbo.calendar with(keepidentity)  
  33. (ID, 
  34. YEAR
  35. QUARTER, 
  36. MONTH
  37. WEEK, 
  38. WEEK_MONTH, 
  39. WORK_DAY, 
  40. IS_HOLIDAY 
  41. )    
  42. select
  43. from    
  44. openrowset(bulk 'c:\calendar.txt',             --要讀取的文件路徑和名稱     
  45.                 formatfile='c:\calendar.fmt'--格式化文件的路徑和名稱    
  46.                    
  47.                 firstrow = 1,                      --要載入的第一行    
  48.                 --lastrow  = 1000,                 --要載入的最後一行,此值必須大於firstrow    
  49.                    
  50.                 maxerrors = 10,                         --在加載失敗以前加載操做中最大的錯誤數    
  51.                 errorfile ='c:\calendar_error.txt', --存放錯誤的文件    
  52.                    
  53.                 rows_per_batch = 100                    --每一個批處理導入的行數    
  54.           ) as calendar    
  55.  
  56.  
  57.  
  58. --3.KEEPDEFAULTS 
  59. insertinto dbo.MDM_CALENDAR with(keepdefaults)  
  60. (   ID           , 
  61.     YEAR        , 
  62.     CAL_QUARTER     , 
  63.     CAL_MONTH        , 
  64.     CAL_WEEK        , 
  65.     CAL_WEEK_OF_MONTH , 
  66.     CAL_DAY    , 
  67.     CAL_DATE       , 
  68.     HOLIDAY        
  69. )    
  70. select
  71. from    
  72. openrowset(bulk 'c:\calendar.txt',             --要讀取的文件路徑和名稱     
  73.                 formatfile='c:\calendar.fmt'--格式化文件的路徑和名稱    
  74.                    
  75.                 firstrow = 1,                      --要載入的第一行    
  76.                 --lastrow  = 1000,                 --要載入的最後一行,此值必須大於firstrow    
  77.                    
  78.                 maxerrors = 10,                         --在加載失敗以前加載操做中最大的錯誤數    
  79.                 errorfile ='c:\calendar_error.txt', --存放錯誤的文件    
  80.                    
  81.                 rows_per_batch = 100                    --每一個批處理導入的行數    
  82.           ) as calendar    
  83.  
  84.  
  85.  
  86. --4.IGNORE_CONSTRAINTS 
  87. --沒法禁用:UNIQUE、PRIMARY KEY 或 NOT NULL約束  
  88. --能夠禁用:CHECK 和 FOREIGN KEY 約束 
  89. insertinto dbo.CALENDAR with(ignore_constraints)  
  90. (   ID, 
  91. YEAR
  92. QUARTER, 
  93. MONTH
  94. WEEK, 
  95. WEEK_MONTH, 
  96. WORK_DAY, 
  97. IS_HOLIDAY       
  98. )    
  99. select
  100. from    
  101. openrowset(bulk 'c:\calendar.txt',             --要讀取的文件路徑和名稱     
  102.                 formatfile='c:\calendar.fmt'--格式化文件的路徑和名稱    
  103.                    
  104.                 firstrow = 1,                      --要載入的第一行    
  105.                 --lastrow  = 1000,                 --要載入的最後一行,此值必須大於firstrow    
  106.                    
  107.                 maxerrors = 10,                         --在加載失敗以前加載操做中最大的錯誤數    
  108.                 errorfile ='c:\calendar_error.txt', --存放錯誤的文件    
  109.                    
  110.                 rows_per_batch = 100                    --每一個批處理導入的行數    
  111.           ) as calendar    
  112.  
  113.  
  114.  
  115.  
  116. --5.IGNORE_TRIGGERS  
  117. --創建觸發器 
  118. createtrigger dbo.calendar_trigger 
  119. on dbo.calendar 
  120. afterinsert 
  121. as 
  122. begin 
  123.  
  124. select * from inserted 
  125. end 
  126. go 
  127.  
  128. insertinto dbo.CALENDAR with(ignore_triggers,ignore_constraints)  
  129. (ID, 
  130. YEAR
  131. QUARTER, 
  132. MONTH
  133. WEEK, 
  134. WEEK_MONTH, 
  135. WORK_DAY, 
  136. IS_HOLIDAY       
  137. )    
  138. select
  139. from    
  140. openrowset(bulk 'c:\calendar.txt',             --要讀取的文件路徑和名稱     
  141.                 formatfile='c:\calendar.fmt'--格式化文件的路徑和名稱    
  142.                    
  143.                 firstrow = 1,                      --要載入的第一行    
  144.                 --lastrow  = 1000,                 --要載入的最後一行,此值必須大於firstrow    
  145.                    
  146.                 maxerrors = 10,                         --在加載失敗以前加載操做中最大的錯誤數    
  147.                 errorfile ='c:\calendar_error.txt', --存放錯誤的文件    
  148.                    
  149.                 rows_per_batch = 100                    --每一個批處理導入的行數    
  150.           ) as calendar  
  151.  
  152.  
  153.  
  154.  
  155.  
  156.  
  157. --6.forceseek 
  158. SELECT *   
  159. FROM sales.SalesOrderHeader o with(forceseek) 
  160. INNERJOIN sales.SalesOrderDetail m with(forceseek, 
  161.                                          index(IX_SalesOrderDetail_ProductID)) 
  162.         ON O.salesorderid = m.salesorderid   
  163.          
  164. innerjoin production.Product e  
  165.    --with(FORCESEEK (PK_Product_ProductID (col1, col2, col3))) 這樣用法在SQL Server2012的 
  166.         on m.ProductID = e.ProductID  
  167.   
  168.   
  169.  
  170. --7.forcescan:在SQL Server2012中引入的,在SQL Server2008不可用 
  171. SELECT *   
  172. FROM sales.SalesOrderHeader o with(FORCESCAN) 
  173. INNERJOIN sales.SalesOrderDetail m with(forcescan, 
  174.                                          index(IX_SalesOrderDetail_ProductID)) 
  175.         ON O.salesorderid = m.salesorderid   
  176.          
  177. innerjoin production.Product e  
  178.    with(forcescan (PK_Product_ProductID (col1, col2, col3)))  
  179.         on m.ProductID = e.ProductID  
  180.   
  181.  
  182. /*============================================= 
  183. 8.鎖定提示 
  184. 鎖粒度: 
  185.     ROWLOCK 
  186.     PAGLOCK 
  187.     TABLOCK(在堆上的delete語句中加上tablock後,在行被刪除時回收分頁)  
  188.  
  189.  
  190. 鎖模式: 
  191.     READPAST:不讀取被鎖定的記錄 
  192.     NOWAIT(SET LOCK_TIMEOUT 0):鎖等待時間爲0,也就是若是須要的數據被鎖定,那麼返回錯誤 
  193.     UPDLOCK:更新鎖 
  194.     XLOCK:獨佔鎖 
  195.     TABLOCKX = TABLOCK + XLOCK 
  196.  
  197.  
  198. 隔離級別: 
  199.     READUNCOMMITTED/NOLOCK 
  200.     READCOMMITTED 
  201.     READCOMMITTEDLOCK:不管數據庫是否設置了快照選項,讀取時都會獲取共享鎖 
  202.     REPEATABLEREAD 
  203.     SERIALIZABLE/HOLDLOCK 
  204.  
  205. ===============================================*/ 
  206. begin tran 
  207.     SELECT
  208.     FROM Production.Product WITH(holdlock) 
  209.  
  210.  
  211.     select
  212.     from sys.dm_tran_locks 
  213.     where request_session_id = @@SPID 
  214. commit tran 
相關文章
相關標籤/搜索