日韩天天综合网_野战两个奶头被亲到高潮_亚洲日韩欧美精品综合_av女人天堂污污污_视频一区**字幕无弹窗_国产亚洲欧美小视频_国内性爱精品在线免费视频_国产一级电影在线播放_日韩欧美内地福利_亚洲一二三不卡片区

SELECT 賦值與ORDER BY沖突的問題_Mssql數(shù)據(jù)庫教程

編輯Tag賺U幣
教程Tag:暫無Tag,歡迎添加,賺取U幣!

推薦:SqlServer2005對現(xiàn)有數(shù)據(jù)進行分區(qū)具體步驟
RegMail是用來存放注冊郵件的表,現(xiàn)以創(chuàng)建時間(CreateTime)字段來給表進行分區(qū),具體步驟如下: --為分區(qū)創(chuàng)建存儲文件 ALTER DATABASE Test ADD FILEGROUP RegMailFile2007 ALTER DATAB

  問題描述:
  使用 SELECT 語句,輪詢表中的數(shù)據(jù),并且處理變量數(shù)據(jù)時,如果有ORDER BY語句,則得不到想要的結(jié)果,但去掉ORDER BY,結(jié)果正常。
  具體的問題表現(xiàn)參考下面的問題重現(xiàn)代碼

  問題重現(xiàn)代碼
  -- 測試數(shù)據(jù)
DECLARE @T TABLE(id int,value nvarchar(16))
INSERT INTO @T SELECT
1, N'好人' UNION ALL SELECT
2, N'壞人' UNION ALL SELECT
3, N'吃飯' UNION ALL SELECT
4, N'垃圾'

  -- 賦值處理
DECLARE @str nvarchar(4000)
SET @str = N'我不是一個好人,也不是垃圾'
SELECT @str = REPLACE(@str, value, N'<u>' value N'</u>')
FROM @T
WHERE CHARINDEX(value, @str) > 0
--ORDER BY CHARINDEX(value, @str) DESC
SELECT @str

/* -- 結(jié)果(當賦值處理語句注釋掉ORDER BY 時)
我不是一個<u>好人</u>,也不是<u>垃圾</u>
-- */

/* -- 結(jié)果(當賦值處理語句加上ORDER BY 時)
我不是一個<u>好人</u>,也不是垃圾
-- */

  問題分析:
  兩個處理語句的結(jié)果不同,通過查看它們的執(zhí)行計劃應(yīng)該可以看出原因所在,為此,通過
SET SHOWPLAN_ALL ON
  輸出了兩種執(zhí)行語句的執(zhí)行計劃(僅StmtText部分,有興趣的讀者在自己的電腦上測試的時候,可以去了解其他部分的信息)

StmtText
Step
DECLARE @str nvarchar(4000) SET @str = N'我不是一個好人,也不是垃圾'
 
SELECT @str = REPLACE(@str, value, N'<u>' value N'</u>') FROM @T WHERE CHARINDEX(value, @str) > 0
4
|--
Compute Scalar(DEFINE:([Expr1002]=replace([@str], @T.[value], '<u>' @T.[value] '</u>')))
3
|--
Filter(WHERE:(charindex(@T.[value], [@str], NULL)>0))
2
|--
Table Scan(OBJECT:(@T))
1
DECLARE @str nvarchar(4000) SET @str = N'我不是一個好人,也不是垃圾'
 
SELECT @str = REPLACE(@str, value, N'<u>' value N'</u>') FROM @T WHERE CHARINDEX(value, @str) > 0 ORDER BY CHARINDEX(value, @str) DESC
5
|--
Sort(ORDER BY:([Expr1003] DESC))
4
|--
Compute Scalar(DEFINE:([Expr1002]=replace([@str], @T.[value], '<u>' @T.[value] '</u>'), [Expr1003]=charindex(@T.[value], [@str], NULL)))
3
|--
Filter(WHERE:(charindex(@T.[value], [@str], NULL)>0))
2
|--
Table Scan(OBJECT:(@T))
1

  從上面的列表可以看出,兩種處理的最大差異,在于賦值前,是否有ORDER BY 子句,從一般的理解上,可能會認為是否排序并不重要,但換個角度來看問題,就比較容易理解為什么有ORDER BY子句后得不到我們想要的結(jié)果了:
當有ORDER BY子句時,對于SELECT @str = 這種賦值處理,SQL Server認為賦值處理肯定只會保留最后一條記錄的處理結(jié)果,而ORDER BY子句確定了數(shù)據(jù)順序,也就知道最后一條記錄是那個,因此只會處理ORDER BY的最后一條記錄。(讀者可以自行去測試一下,調(diào)整ORDER BY順序,看看結(jié)果是否與我的推論相符)
當沒有ORDER BY子句時,因為無法確定數(shù)據(jù)順序,所以SQL Server必須掃描滿足條件的每條數(shù)據(jù)來得到結(jié)果,這樣每掃描一條記錄都會處理一次,所以結(jié)果是我們所預知的

  問題解決方法:
  修改處理語句,使查詢優(yōu)化器使用與我們需要結(jié)果一致的執(zhí)行方法,可以解決這個問題。
對于示例中的處理語句,可以調(diào)整如下:
DECLARE @str nvarchar(4000)
SET @str = N'我不是一個好人,也不是垃圾'
SELECT @str = REPLACE(@str, value, N'<u>' value N'</u>')
FROM(
SELECT TOP 100 PERCENT
value
FROM @T
WHERE CHARINDEX(value, @str) > 0
ORDER BY CHARINDEX(value, @str) DESC
)A
SELECT @str

  補充:
  此問題的結(jié)論只是筆者對于查詢分析的一個推論,并無相應(yīng)的官方文檔可以證明,所以歡迎大家發(fā)表自己的看法

分享:講解數(shù)據(jù)庫調(diào)優(yōu)與程序員相關(guān)的幾個方面
許多程序員在面試時,經(jīng)常會被問到 “數(shù)據(jù)庫調(diào)優(yōu)”的事情,這時,許多人就會產(chǎn)生疑問,這不是DBA的事嗎,但回答不好還是顯得不夠?qū)I(yè),筆者查找了一些相關(guān)資料,發(fā)現(xiàn)許多方面還真是程

來源:模板無憂//所屬分類:Mssql數(shù)據(jù)庫教程/更新時間:2008-08-22
相關(guān)Mssql數(shù)據(jù)庫教程