亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數據庫 > SQL Server > 正文

多列復合索引的使用 繞過微軟sql server的一個缺陷

2024-08-31 00:57:13
字體:
來源:轉載
供稿:網友
然而,微軟sql server在處理這類索引時,有個重要的缺陷,那就是把本該編譯成索引seek的操作編成了索引掃描,這可能導致嚴重性能下降

舉個例子來說明問題,假設某個表T有索引 ( cityid, sentdate, userid), 現在有個分頁列表功能,要獲得大于某個多列復合索引V0的若干個記錄的查詢,用最簡單表意的方式寫出來就是 V >= V0, 如果分解開來,就是:
cityid > @cityid0 or (cityid = @cityid0 and (sentdate > @sentdate0 or (sentdate = @sentdate0 and userid >= @userid0))),

當你寫出上述查詢時,你會期待sql server會自動的把上述識別為V >= V0類型的邊界條件,并使用index seek操作來實施該查詢。然而,微軟的sql server (2005版)有一個重要缺陷(其他的sql server如何還不得知), 當它遇到這樣sql時,sql server就會采用index scan來實施,結果是您建立好的索引根本就沒有被使用,如果這個表的數據量很大,那所造成的性能下降是非常大的。
對于這個問題,我曾經提交給微軟的有關人士,他們進一步要求我去一個正式的網站上去提交這個缺陷,我懶得去做。

不過,對這個缺陷,還是有個辦法能夠繞過去的,只要把上面給出的條件變變形,sql server還是能夠變回到是用index seek, 而不是低性能的index scan. 具體請看我的英文原文吧(對不起了, 我一旦寫了中文,就不想翻成英文,反過來也一樣, 估計大家英文都還可以,實在不行的就看黑體部分吧, ):
The seek predicate of the form "x > bookmark_of_x" is needed in paging related query. The compiler has no difficulty to parse it correctly if x is a single column index, or two columns index, however, if x is a three columns index or more, then the compiler will have a hard time to recognize it. This failure will result in that the seek predicate ended up in residue predicate, which results in a much worse execution plan.
To illustrate the point, take a example,
Create table A( a int, b int, c int, d float, primary key (a, b, c))
now check the plan for the query:
select c, d from A where (a> 111 or a= 111 and
(b > 222 or b = 222 and c > 333))
you can see a table scan op is used, and the Where clause ended up in residue predicate.
However, if you rewrite the query in an equivalent form:
select c, d from A where a> 111 or a= 111 and b > 222 or a= 111 and b= 222 and c >333
Then the compiler can choose an index seek op, which is desired.
The problem is, the compiler should be able to recognize the first form of seek predicate on multiple columns index, it saves the user from having to pay extra time to figure out a get-around, not to mention the first form is a more efficient form of same expression.
上面的問題,可以說是部分的繞過去了,但是,也有繞不過的時候,接著看下面一段:
It looks like that sql server lacks a consept of vector bookmark, or vector comparison or whatever you like to call it.
The workaround is not a perfect workaround. If sql server were to understand the concept of vector bookmark, then the following two would be the same in execution plan and performance:
1. select top(n) * from A where vectorIndex >= @vectorIndex
2. select * from A where vectorIndex >= @vectorIndex and vectorIndex <=@vectorIndexEnd
-- @vectorIndexEnd corresponds to the last row of 1.
However, test has shown that, the second statement takes far more time than the first statement, and sql server actually only seek to the begining of the vector range and scan to the end of the whole Index, instead of stop at the end of the vector range.
Not only sql server compile badly when the vector bookmark has 3 columns, test has shown that even with as few as 2 columns, sql serer still can not correctly recognize this is actually a vector range, example:
3. select top (100) a, b, c, d from A where a> 60 or a= 60 and b > 20
4. select a, b, c, d from A where (a> 60 or a= 60 and b > 20) and
(a< 60 or a= 60 and b <= 21),

上面兩個查詢實質相同(表中的數據剛好如此),并且給出同業的結果集,但是,3比4的速度要快的多,如果去看execution plan也證明3確實應當比4快.
也就是說, 即使在索引vectorIndex只含兩列的情況下, sql server也無法正確的理解范圍表達式 @vectorIndex0 < vectorIndex < @vectorIndex1, 它能把前半部分正確的解讀為seek, 但是, 后半部分無法正確解讀, 導致, sql server會一直掃描到整個表的末尾, 而不是在@vectorIndex1處停下來.
以下測試代碼, 有興趣的人可以拿去自己玩:

復制代碼 代碼如下:


CREATE TABLE [dbo].[A](
[a] [int] NOT NULL,
[b] [int] NOT NULL,
[c] [int] NOT NULL,
[d] [float] NULL,
PRIMARY KEY CLUSTERED ([a] ASC, [b] ASC, [c] ASC)
)
declare @a int, @b int, @c int
set @a =1
while @a <= 100
begin
set @b = 1
begin tran
while @b <= 100
begin
set @c = 1
while @c <= 100
begin
INSERT INTO A (a, b, c, d)
VALUES (@a,@b,@c,@a+@b+@c)
set @c = @c + 1
end
set @b = @b + 1
end
commit
set @a = @a + 1
end
SET STATISTICS PROFILE ON
SET STATISTICS time ON
SET STATISTICS io ON

select top (10) a, b, c, d from A where (a> 60 or a= 60 and
(b > 20 or b = 20 and c >= 31))
select a, b, c, d from A where (a> 60 or a= 60 and
(b > 20 or b = 20 and c >= 31)) and (a< 60 or a= 60 and
(b < 20 or b = 20 and c <= 40))

select top (10) a, b, c, d from A where a> 60 or a= 60 and b > 20 or a= 60 and b= 20 and c >= 31
select a, b, c, d from A where (a> 60 or a= 60 and b > 20 or a= 60 and b= 20 and c >= 31) and
(a< 60 or a= 60 and b < 20 or a= 60 and b= 20 and c <= 40)
select top (100) a, b, c, d from A where a> 60 or a= 60 and b > 20
select a, b, c, d from A where (a> 60 or a= 60 and b > 20) and (a< 60 or a= 60 and b <= 21)
select top (100) a, b, c, d from A where a> 60 or a= 60 and b > 20
select a, b, c, d from A where (a> 60 or a= 60 and b > 20) and (a< 60 or a= 60 and b <= 21)

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品成人va在线观看| 日本精品免费一区二区三区| 动漫精品一区二区| 国产精品一区二区av影院萌芽| 国产精品电影一区| 午夜免费久久久久| 国产亚洲精品久久久久久| 欧美性受xxx| 97在线看免费观看视频在线观看| 亚洲精品小视频| 26uuu日韩精品一区二区| 中文字幕欧美日韩va免费视频| 国产不卡一区二区在线播放| 热门国产精品亚洲第一区在线| 欧美高清性猛交| 成人午夜黄色影院| 亚洲三级免费看| 久久人人看视频| 欧美有码在线视频| 2019亚洲日韩新视频| 亚洲精品久久久久久久久| 国产亚洲一区精品| 美女啪啪无遮挡免费久久网站| 亚洲性视频网站| 91欧美精品成人综合在线观看| 欧美成人精品不卡视频在线观看| 欧美激情视频网址| 韩曰欧美视频免费观看| 国产精品观看在线亚洲人成网| 国产精品自产拍在线观看| 日韩欧美黄色动漫| 色综合久久88色综合天天看泰| 日韩一区在线视频| 久久精品国产99国产精品澳门| 自拍偷拍免费精品| 国产精品视频男人的天堂| 日韩av不卡在线| 欧美丝袜美女中出在线| 国产精品一区久久久| 在线电影av不卡网址| 亚洲精品综合精品自拍| 国产精品免费网站| 91精品在线一区| 日韩av电影在线免费播放| 亚洲成人中文字幕| 亚洲精品动漫久久久久| 欧美亚洲一级片| 国产精品日日做人人爱| 富二代精品短视频| 中文字幕日韩精品在线观看| 亚洲第一免费网站| 国产精品一区二区三区毛片淫片| 国产精品免费观看在线| 成人在线播放av| 亚洲成人中文字幕| 欧美丰满片xxx777| 国产精品视频午夜| 日韩在线小视频| 亚洲精品欧美日韩| 欧美乱妇高清无乱码| 亚洲天堂网站在线观看视频| 色播久久人人爽人人爽人人片视av| 欧美性生活大片免费观看网址| 欧美有码在线观看视频| 日韩福利视频在线观看| 久久久久久尹人网香蕉| 国产欧美日韩丝袜精品一区| 欧美日韩国产精品一区二区三区四区| 欧美精品情趣视频| 亚洲视频精品在线| 欧美黑人性生活视频| 欧美精品少妇videofree| 国产精品久久久久久久久久东京| 亚洲成人精品视频在线观看| 91国在线精品国内播放| 久久香蕉频线观| 欧美日韩国产精品一区二区不卡中文| 国产精品欧美日韩一区二区| 欧美精品日韩www.p站| 97在线视频一区| 色99之美女主播在线视频| 国产精品一区二区女厕厕| 欧美区在线播放| 国内精品久久久久影院 日本资源| 中文字幕日本欧美| 久久久久久久久网站| 成人乱人伦精品视频在线观看| 成人精品网站在线观看| 亚洲午夜色婷婷在线| 国产欧美一区二区三区久久人妖| 亚洲精品久久久久中文字幕二区| 97久久精品视频| 欧美日韩国产第一页| 国产经典一区二区| 国精产品一区一区三区有限在线| 国产美女扒开尿口久久久| 欧美在线www| 最近的2019中文字幕免费一页| 成人久久久久久| 91精品久久久久久久久不口人| 黑人狂躁日本妞一区二区三区| 2019精品视频| 欧美日韩福利在线观看| 久久天天躁狠狠躁夜夜av| 久久久久亚洲精品| 亚洲free性xxxx护士hd| 亚洲国产欧美一区| 68精品国产免费久久久久久婷婷| 亚洲乱码一区av黑人高潮| 欧美极品美女电影一区| 91免费看片网站| 日韩亚洲欧美中文高清在线| 日韩毛片在线观看| 国内精品久久久久影院 日本资源| 国产成人福利夜色影视| 成人网在线观看| 久久久av网站| 欧美与黑人午夜性猛交久久久| 亚洲精品不卡在线| 日韩精品在线观看视频| 狠狠色噜噜狠狠狠狠97| 欧美日韩免费区域视频在线观看| 国产精品日韩在线播放| 亚洲一区制服诱惑| 亚洲色图综合网| 丝袜一区二区三区| 成人性教育视频在线观看| 亚洲欧美国产精品久久久久久久| 欧美二区乱c黑人| 日韩亚洲欧美成人| 亚洲伊人成综合成人网| 欧美成人精品在线观看| 成人免费视频在线观看超级碰| 亚洲最大福利网站| 亚洲一区二区久久久久久久| 日韩av在线网站| 国产精品白丝jk喷水视频一区| 538国产精品一区二区免费视频| 另类天堂视频在线观看| 秋霞成人午夜鲁丝一区二区三区| 国产精品1234| 日本高清+成人网在线观看| 国产视频在线观看一区二区| 久久亚洲精品中文字幕冲田杏梨| 欧美成人免费小视频| 亚洲精品小视频在线观看| 亚洲日本中文字幕免费在线不卡| 欧美在线视频一区| 国产欧美一区二区三区四区| 国产97在线|亚洲| 亚洲成人黄色在线观看| 亚洲人成网站免费播放| 欧美性猛交xxxx乱大交极品| 日日狠狠久久偷偷四色综合免费| 国产精品成人av性教育| 2019最新中文字幕| 91久久久久久国产精品| 欧美寡妇偷汉性猛交| 伊人久久久久久久久久| 亚洲激情视频网站| 中文字幕在线观看亚洲| 国产香蕉97碰碰久久人人| 久久久精品国产一区二区| 最近日韩中文字幕中文|