国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 開(kāi)發(fā) > 綜合 > 正文

用SQLServer2000索引視圖提高性能(下)

2024-07-21 02:10:53
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
使用“索引微調(diào)向?qū)А?

“索引微調(diào)向?qū)А背ㄗh使用基表的索引之外,還建議使用索引視圖。使用該向?qū)Э商岣吖芾韱T確定索引和索引視圖相結(jié)合的能力,從而優(yōu)化針對(duì)數(shù)據(jù)庫(kù)執(zhí)行的典型混合查詢的性能。

由于“索引微調(diào)向?qū)А睆?qiáng)制使用所有必需的 set 選項(xiàng)(以確保結(jié)果集的正確性),其索引視圖將會(huì)成功創(chuàng)建。不過(guò),如果您的應(yīng)用程序的選項(xiàng)沒(méi)有按照要求設(shè)置,可能無(wú)法利用這些視圖。對(duì)那些參與索引視圖定義的表執(zhí)行的插入、更新或刪除操作可能會(huì)失敗。


維護(hù)索引視圖

sql server 自動(dòng)維護(hù)索引視圖,這與維護(hù)任何其它索引的情況類似。對(duì)于普通索引而言,每個(gè)索引都直接連接到單個(gè)表。通過(guò)對(duì)基礎(chǔ)表執(zhí)行每個(gè) insert、update 或 delete 操作,索引相應(yīng)地進(jìn)行了更新,以便使存儲(chǔ)在該索引中的值始終與表一致。

索引視圖的維護(hù)與此類似。不過(guò),如果視圖引用了多個(gè)表,則對(duì)這些表中的任何一個(gè)進(jìn)行更新都需要更新索引視圖。與普通索引不同的是,對(duì)任何一個(gè)參與的表執(zhí)行一次行插入操作都可能導(dǎo)致在索引視圖中進(jìn)行多次行插入操作。更新和刪除操作的情況也是如此。因此,較之于維護(hù)表的索引,維護(hù)索引視圖的代價(jià)更為高昂。

在 sql server 2000 中,某些視圖可以更新。如果某個(gè)視圖可以更新,則使用 insert、update 和 delete 語(yǔ)句可通過(guò)該視圖直接修改根本基表。為某個(gè)視圖創(chuàng)建索引并不會(huì)妨礙該視圖的更新。有關(guān)可更新視圖的詳細(xì)信息,請(qǐng)參閱關(guān)于 sql server 2000 的“sql server 聯(lián)機(jī)圖書(shū)”中的“通過(guò)視圖修改數(shù)據(jù)(英文)”。

維護(hù)成本的考慮因素

設(shè)計(jì)索引視圖時(shí)應(yīng)該考慮以下幾點(diǎn):

數(shù)據(jù)庫(kù)中需要有一個(gè)額外的存儲(chǔ)空間用于索引視圖。索引視圖的結(jié)果集以類似于典型表存儲(chǔ)空間的方式物理保存在數(shù)據(jù)庫(kù)中。
sql server 自動(dòng)維護(hù)視圖。因此,對(duì)定義視圖所據(jù)的基表的任何更改都可能引起視圖索引的一處或多處更改,從而導(dǎo)致維護(hù)開(kāi)銷的增加。
一個(gè)視圖獲得的凈性能提高就是視圖提供的查詢執(zhí)行節(jié)約總計(jì)與存儲(chǔ)和維護(hù)該視圖耗費(fèi)的成本之間的差。

估計(jì)視圖將占用的所需存儲(chǔ)空間要相對(duì)簡(jiǎn)單一些。用 sql 查詢分析器的“顯示估計(jì)的執(zhí)行計(jì)劃”工具求視圖定義中 select 語(yǔ)句的值。該工具將得出查詢返回的行數(shù)和行大小的近似值。將這兩個(gè)值相乘,即可估計(jì)出視圖的可能大小。不過(guò)這只是一個(gè)近似值。視圖索引的實(shí)際大小只能通過(guò)創(chuàng)建視圖索引來(lái)精確得出。

從 sql server 執(zhí)行的自動(dòng)維護(hù)考慮因素的觀點(diǎn)出發(fā),“顯示估計(jì)的執(zhí)行計(jì)劃”的功能可能會(huì)對(duì)此開(kāi)銷的影響有所了解。如果用 sql 查詢分析器評(píng)估修改視圖的語(yǔ)句(針對(duì)視圖的 update 語(yǔ)句、針對(duì)基表的 insert 語(yǔ)句),showplan 將包括該語(yǔ)句的維護(hù)操作。同時(shí)考慮此成本和此操作將在生產(chǎn)環(huán)境中發(fā)生的次數(shù),可以指示視圖維護(hù)的可能成本。

通常建議對(duì)視圖或基表進(jìn)行的任何修改和更新都應(yīng)該盡可能地成批執(zhí)行,而不要單獨(dú)進(jìn)行。這樣可以減少視圖維護(hù)的某些開(kāi)銷。


創(chuàng)建索引視圖

創(chuàng)建索引視圖所需的步驟與視圖的成功實(shí)現(xiàn)密不可分。

確保將在視圖中引用的所有現(xiàn)有表的 set 選項(xiàng)都正確。
創(chuàng)建任何新表和視圖之前,確保會(huì)話的 set 選項(xiàng)已正確設(shè)置。
確保視圖定義是確定的。
使用 with schemabinding 選項(xiàng)創(chuàng)建視圖。
創(chuàng)建視圖的唯一群集索引。

使用 set 選項(xiàng)以獲得一致的結(jié)果

如果在執(zhí)行查詢時(shí)啟用不同的 set 選項(xiàng),則在 sql server 中對(duì)同一個(gè)表達(dá)式求值會(huì)產(chǎn)生不同的結(jié)果。例如,將 set 選項(xiàng) concat_null_yields_null 設(shè)置為 on 之后,表達(dá)式 'abc' + null 返回的值是 null。而將 concat_null_yieds_null 設(shè)置為 off 之后,該表達(dá)式得出的結(jié)果卻是 'abc'。索引視圖要求多個(gè) set 選項(xiàng)的值都固定,以確保這些視圖能夠得到正確維護(hù)并返回一致的結(jié)果。

只要出現(xiàn)以下情況,就必須將下表中的 set 選項(xiàng)設(shè)置為要求的值列中所示的值:

創(chuàng)建了索引視圖。
對(duì)索引視圖中引用的任何表執(zhí)行了任何 insert、update 或 delete 操作。
查詢優(yōu)化器使用索引視圖來(lái)生成查詢計(jì)劃。
set
選項(xiàng) 要求
的值 默認(rèn)
服務(wù)器
的值 ole db

odbc 的值 db lib
的值
ansi_nulls on off on off
ansi_padding on on on off
ansi_warning on off on off
arithabort on off off off
concat_null_yields_null on off on off
numeric_roundabort off off off off
quoted_identifier on off on off


如果使用的是 ole db 或 odbc 服務(wù)器連接,唯一必須修改的值是 arithabort 的設(shè)置。所有 db lib 值都必須使用 sp_configure 在服務(wù)器級(jí)上正確設(shè)置或使用 set 命令從應(yīng)用程序正確設(shè)置。有關(guān) set 選項(xiàng)的詳細(xì)信息,請(qǐng)參閱關(guān)于 sql server 2000 的“sql server 聯(lián)機(jī)圖書(shū)”中的“使用 sql server 中的選項(xiàng)(英文)”。


使用確定性函數(shù)

索引視圖的定義必須是確定性的。如果選擇列表中的所有表達(dá)式以及 where 和 group by 子句都是確定性的,則視圖就是確定性的。只要用特定的一組輸入值對(duì)確定性表達(dá)式進(jìn)行求值,一定會(huì)返回同一個(gè)結(jié)果。只有確定性函數(shù)可以加入確定性表達(dá)式。例如,dateadd 是確定性函數(shù),因?yàn)閷⑷魏谓o定的一組變量值賦予它的三個(gè)參數(shù)進(jìn)行求值,返回的總是同一個(gè)結(jié)果。而 getdate 則不是確定性函數(shù),因?yàn)槭冀K用同一個(gè)變量調(diào)用它,而它每次執(zhí)行后返回的值都不相同。有關(guān)詳細(xì)信息,請(qǐng)參閱關(guān)于 sql server 2000 的“sql server 聯(lián)機(jī)圖書(shū)”中的“確定性和非確定性函數(shù)”。

即便某個(gè)表達(dá)式是確定性的,但如果其中包含浮動(dòng)表達(dá)式,確切的結(jié)果就可能取決于處理器的體系結(jié)構(gòu)或微代碼的版本。要確保 sql server 2000 中數(shù)據(jù)的完整性,此類表達(dá)式只能加入索引視圖的非關(guān)鍵列。不包含浮動(dòng)表達(dá)式的確定性表達(dá)式被稱為精確的表達(dá)式。只有精確的確定性表達(dá)式可以加入索引視圖的關(guān)鍵列和 where 或 group by 子句。

使用 columnproperty 函數(shù)和 isdeterministic 屬性來(lái)確定視圖列是否是確定性的。使用 columnproperty 函數(shù)和 isprecise 屬性來(lái)確定包含架構(gòu)綁定的視圖中的確定性列是否是精確的。如果為 true,則 columnproperty 會(huì)返回 1,如果為 false,則返回 0,如果是無(wú)效的輸入(列不是確定性的),則返回 null。例如,select columnproperty(object_id('vdiscount1'),'sumdiscountprice','isprecise') 返回的是 0,因?yàn)?sumdiscountprice 列引用了表 order details 中的浮動(dòng)列 discount。而同一視圖中的列 sumprice 既是確定性的又是精確的。

注意:   該 select 語(yǔ)句所基于的視圖能夠在示例部分找到(視圖 1)。


其它要求

除“設(shè)計(jì)準(zhǔn)則”、“使用 set 選項(xiàng)以獲得一致的結(jié)果”和“使用確定性函數(shù)”部分中列出的要求之外,還必須符合以下要求。

基表要求

基表在創(chuàng)建時(shí)必須正確設(shè)置 set 選項(xiàng),否則就不能被包含架構(gòu)綁定的視圖引用。
表必須通過(guò)視圖定義中的兩部分名稱(所有者.表名)引用。
函數(shù)要求

用戶定義的函數(shù)必須使用 with schemabinding 選項(xiàng)創(chuàng)建。
用戶定義的函數(shù)必須通過(guò)兩部分名稱(所有者.函數(shù))引用。
視圖要求

視圖必須使用 with schemabinding 選項(xiàng)創(chuàng)建。
視圖必須只引用同一數(shù)據(jù)庫(kù)中的基表,而不能引用其它視圖。
語(yǔ)法限制

對(duì)視圖定義的語(yǔ)法有幾個(gè)限制。視圖定義不能包含以下內(nèi)容:

count(*)
rowset 函數(shù)
派生表
自聯(lián)接
distinct
stdev、variance、avg
float* 列、文本列、ntext 列、圖像列
子查詢
全文謂詞(contain、freetext)
可空表達(dá)式的 sum
min、max
top
outer 聯(lián)接
union
注意:   索引視圖可以包含浮動(dòng)列,不過(guò),此類列不能包含在群集索引關(guān)鍵字中。

group by 限制

如果未使用 group by,表達(dá)式不能在選擇列表中使用。

如果使用了 group by,則 view 定義:

必須包含 count_big(*)。
不得包含 having、cube 或 rollup。
這些限制只適用于索引視圖定義。查詢可以在其執(zhí)行計(jì)劃中使用索引視圖,即便該索引視圖并不符合這些 group by 限制。

索引要求

執(zhí)行 create index 語(yǔ)句的用戶必須是視圖所有者。
如果視圖定義中包含 group by 子句,唯一群集索引的關(guān)鍵字只能引用 group by 子句中指定的列。

示例

本部分的示例闡述索引視圖在兩種主要查詢(聚合和聯(lián)接)中的使用問(wèn)題。同時(shí)還說(shuō)明查詢優(yōu)化器在確定某個(gè)索引視圖是否可用時(shí)使用的條件。有關(guān)這些條件的完整列表,請(qǐng)參閱查詢優(yōu)化器如何使用索引視圖。

查詢基于 northwind(sql server 2000 中提供的數(shù)據(jù)庫(kù)樣本)中的表,并可以寫(xiě)入的方式執(zhí)行。創(chuàng)建視圖的前后,最好使用 sql 查詢優(yōu)化器中的“顯示執(zhí)行計(jì)劃”工具來(lái)查看查詢優(yōu)化器選定的計(jì)劃。盡管示例中闡述了優(yōu)化器是如何選擇成本最低的執(zhí)行計(jì)劃的,但因?yàn)?northwind 數(shù)據(jù)庫(kù)樣本太小,因此無(wú)法體現(xiàn)性能的提高。

以下查詢顯示如何從 order details 表中返回具有最大總折扣的五種產(chǎn)品的兩個(gè)方法。

查詢 1

select top 5 productid, sum(unitprice*quantity) -
sum(unitprice*quantity*(1.00-discount))as rebate
from [order details]
group by productid
order by rebate desc

查詢 2

select top 5 productid, sum(unitprice*quantity*discount)as rebate
from [order details]
group by productid
order by rebate desc

查詢優(yōu)化器選定的執(zhí)行計(jì)劃包含:

對(duì) order details 表的群集索引掃描,估計(jì)有 2,155 行。
哈希匹配/聚合運(yùn)算符,該運(yùn)算符基于 group by 列將選定的行放入哈希表,然后計(jì)算每行的 sum 聚合。
基于 order by 子句的 top 5 排序運(yùn)算符。
視圖 1

添加包括 rebate 列所需聚合的索引視圖將更改查詢 1 的查詢執(zhí)行計(jì)劃。在數(shù)百萬(wàn)行的大表上,查詢的性能也將明顯提高。

create view vdiscount1 with schemabinding
as
select sum(unitprice*quantity)as sumprice,
sum(unitprice*quantity*(1.00-discount))
as sumdiscountprice, count_big(*) as count, productid
from dbo.[order details]
group by productid
   go
create unique clustered index vdiscountind on vdiscount1 (productid)

第一個(gè)查詢的執(zhí)行計(jì)劃顯示 vdiscount1 視圖由查詢優(yōu)化器使用。不過(guò),由于該視圖不包含 sum(unitprice*quantity*discount) 聚合,因此不會(huì)被第二個(gè)查詢使用。可以創(chuàng)建另一個(gè)可以同時(shí)滿足上述兩個(gè)查詢的索引視圖。

視圖 2

create view vdiscount2 with schemabinding
as
select sum(unitprice*quantity)as sumprice,
sum(unitprice*quantity*(1.00-discount))as sumdiscountprice,
sum(unitprice*quantity*discount)as sumdiscountprice2, count_big(*)
as count, productid
from dbo.[order details]
group by productid
go
create unique clustered index vdiscountind on vdiscount2 (productid)

有了該索引視圖,現(xiàn)在兩個(gè)查詢的查詢執(zhí)行計(jì)劃包含:

對(duì) vdiscount2 視圖的群集索引掃描,估計(jì)有 77 行
基于 order by 子句的 top 5 排序函數(shù)
查詢優(yōu)化器選擇該視圖是因?yàn)樗峁┝俗畹偷膱?zhí)行成本,盡管在查詢中并未引用該視圖。

查詢 3

查詢 3 類似于前幾個(gè)查詢,只是 productid 已被 orderid 所取代,視圖定義中沒(méi)有包括該列。這違背了以下條件:查詢選擇列表中的所有表達(dá)式都必須能從未包括在視圖定義內(nèi)的表的視圖選擇列表中派生。

select top 3 orderid, sum(unitprice*quantity*discount) orderrebate
from dbo.[order details]
group by orderid
order by orderrebate desc

要求單獨(dú)的索引視圖來(lái)滿足該查詢。可以對(duì) vdiscount2 進(jìn)行修改,使它包括 orderid,但是所生成視圖的行數(shù)將與原表的行數(shù)相同,因此,提供的性能也不會(huì)高于使用基表所提供的性能。

查詢 4

該查詢可生成每個(gè)產(chǎn)品的平均價(jià)格。

select productname, od.productid,
avg(od.unitprice*(1.00-discount)) as avgprice, sum(od.quantity) as units
from [order details] od, products p
where od.productid=p.productid
group by productname, od.productid

索引視圖的定義中不能包括復(fù)雜的聚合(例如,stdev、variance、avg),不過(guò),如果索引視圖中包括幾個(gè)聯(lián)合起來(lái)執(zhí)行復(fù)雜聚合的簡(jiǎn)單聚合函數(shù),即可用于執(zhí)行包含 avg 的查詢。

視圖 3

該索引視圖包含執(zhí)行 avg 函數(shù)所需的簡(jiǎn)單聚合函數(shù)。在創(chuàng)建了視圖 3 后執(zhí)行查詢 4 時(shí),執(zhí)行計(jì)劃會(huì)顯示正被使用的視圖。優(yōu)化器可以從視圖的簡(jiǎn)單聚合列 price 和 count 中導(dǎo)出 avg 表達(dá)式。

create view view3 with schemabinding
as
select productid, sum(unitprice*(1.00-discount))as price,
count_big(*)as count, sum(quantity)as units
from dbo.[order details]
group by productid
go
create unique clustered index iv3 on view3 (productid)

查詢 5

該查詢與查詢 4 相同,只不過(guò)包括一個(gè)附加搜索條件。即使該附加搜索條件只引用未包括在視圖定義內(nèi)的表中的列,視圖 3 也將用于該查詢。

select productname, od.productid, avg(od.unitprice*(1.00-discount))
as avgprice, sum(od.quantity)as units
from [order details] as od, products as p
where od.productid=p.productid
and p.productname like '%tofu%'
group by productname, od.productid

查詢 6

查詢優(yōu)化器不能將視圖 3 用于該查詢。附加搜索條件 od.unitprice>10 包含視圖定義內(nèi)的表中的列,而該列卻不出現(xiàn)在 group by 列表中,搜索謂詞也不出現(xiàn)在視圖定義中。

select productname, od.productid, avg(od.unitprice*(1.00-discount))
as avgprice, sum(od.quantity) as units
from [order details] od, products p
where od.productid = p.productid
and od.unitprice > 10
group by productname, od.productid

查詢 7

相反,查詢優(yōu)化器可以將視圖 3 用于查詢 7,原因是新搜索條件 od.productid in (1,2,13,41) 中定義的列包括在視圖定義內(nèi)的 group by 子句中。

select productname, od.productid, avg(od.unitprice*(1.00-discount))
as avgprice, sum(od.quantity) as units
from [order details] as od, products as p
where od.productid = p.productid
and od.productid in (1,2,13,41)
group by productname, od.productid

視圖 4

該視圖在視圖定義中包括了列 od.discount,可以滿足查詢 6 的條件。

create view view4 with schemabinding
as
select productname, od.productid, sum(od.unitprice*(1.00-discount))
as avgprice, sum(od.quantity) as units, count_big(*) as count
from dbo.[order details] as od, dbo.products as p
where od.productid = p.productid
and od.unitprice > 10
group by productname, od.productid
go
create unique clustered index vdiscountind on view4 (productname, productid)

查詢 8

視圖 4 的同一個(gè)索引還將用于一個(gè)添加了與表 orders 的聯(lián)接的查詢。該查詢符合以下條件:查詢 from 子句中列出的表是索引視圖的 from 子句中表的超集。

select productname, od.productid, avg(od.unitprice*(1.00-discount))
as avgprice, sum(od.quantity) as units
from dbo.[order details] as od, dbo.products as p, dbo.orders as o
where od.productid = p.productid and o.orderid = od.orderid
and od.unitprice > 10
group by productname, od.productid

最后兩個(gè)查詢是查詢 8 的變體。每個(gè)變體都違背了一個(gè)優(yōu)化器條件,因此與查詢 8 不同,不能使用視圖 4。

查詢 8a

由于視圖定義中的 unitprice > 10 與查詢中的 unitprice > 25 之間的 where 子句不匹配,所以 q8a 不能使用索引視圖。查詢搜索條件謂詞必須是視圖定義中搜索條件謂詞的超集。

select productname, od.productid, avg(od.unitprice*(1.00-discount)) avgprice,
sum(od.quantity) as units
from dbo.[order details] as od, dbo.products as p, dbo.orders as o
where od.productid = p.productid and o.orderid = od.orderid
and od.unitprice > 25
group by productname, od.productid

查詢 8b

注意,表 orders 沒(méi)有參與索引視圖 v4 的定義。盡管如此,在該表中添加謂詞將禁止使用索引視圖,原因是添加的謂詞可能會(huì)消除聚合中的其它行(如查詢 8b 中所示)。

select productname, od.productid, avg(od.unitprice*(1.00-discount))
as avgprice, sum(od.quantity) as units
from dbo.[order details] as od, dbo.products as p, dbo.orders as o
where od.productid = p.productid and o.orderid = od.orderid
and od.unitprice > 10
and o.orderdate > '01/01/1998'
group by productname, od.productid


有關(guān)詳細(xì)信息

microsoft sql server 2000 聯(lián)機(jī)圖書(shū)包含索引視圖的詳細(xì)信息。有關(guān)其它信息,請(qǐng)參閱以下資源:

microsoft sql server web 站點(diǎn)(英文)。
microsoft sql server 開(kāi)發(fā)人員中心(英文)。
sql server 雜志(英文)。
microsoft.public.sqlserver.server 和 microsoft.public.sqlserver.datawarehouse 新聞組,其站點(diǎn)是:news://news.microsoft.com(英文)。
關(guān)于 sql server 的 microsoft 正式課程。有關(guān)最新的課程信息,請(qǐng)參閱 microsoft 培訓(xùn)和服務(wù)站點(diǎn)(英文)。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 化州市| 云阳县| 扶沟县| 瑞昌市| 铜山县| 三门峡市| 渝北区| 洛隆县| 房产| 遵化市| 北票市| 宝丰县| 西昌市| 临澧县| 金坛市| 申扎县| 大渡口区| 红桥区| 虞城县| 乾安县| 开阳县| 乐安县| 延庆县| 祁东县| 余干县| 巴青县| 贺兰县| 佛教| 鲁甸县| 昭觉县| 大宁县| 运城市| 台东县| 佛学| 永宁县| 赤壁市| 楚雄市| 大渡口区| 延川县| 平陆县| 柯坪县|