【轉載】怎樣提高SQL的執行效率(討論)

如果說SQL的執行計劃與數據表中數據的多少有關,有人相信嗎?
 
先看下面這樣一個表:
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[test]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
 drop table test
go
--建表
create table test(id varchar(10) not null,name varchar(20) not null) on [PRIMARY]
go
--建主鍵、索引
ALTER TABLE test ADD CONSTRAINT PK_test PRIMARY KEY NONCLUSTERED (id) ON [PRIMARY]
CREATE INDEX IX_test_name ON test(name) ON [PRIMARY]
go
 
問題:對於上面這樣一個表,下面的查詢語句是否有區別?
1.
select * from test where name>'名稱0000000001'
go
2.
declare @id varchar(20)
set @id='名稱0000000001'
select * from test where name>@id
go
 
 
 回覆人: tx1icenhe(冒牌馬可 V0.1) ( ) 信譽:100 2004-07-14 10:38:00 得分: 0 
 
 
   雖然老生常談,但是確實有討論必要,支持
 
SQL的執行計劃與數據表中數據的多少有關,有人相信嗎?
當然相信
 
 
 
 
Top 
 
 回覆人: pbsql(風雲) ( ) 信譽:106 2004-07-14 10:46:00 得分: 0 
 
 
   在查詢分析器,可以看分析:(沒有數據的情況)
SELECT成本:0%
Bookmark Lookup成本:49%
test.IX_test_name Index Seek成本:51%
 
下面來增加100條數據:
truncate table test
select top 100 identity(int,1,1) id into #t from syscolumns a,syscolumns b,syscolumns c
insert into test(id,name)
 select right('0000000000'+cast(id as varchar),10),'名稱'+right('0000000000'+cast(id as varchar),10) from #t
drop table #t
再看執行計劃,1、2的執行計劃沒有變化。
 
但是如果增加10000條數據或是更多呢:
truncate table test
select top 10000 identity(int,1,1) id into #t from syscolumns a,syscolumns b,syscolumns c
insert into test(id,name)
 select right('0000000000'+cast(id as varchar),10),'名稱'+right('0000000000'+cast(id as varchar),10) from #t
drop table #t
 
再看執行計劃,1、2的執行計劃就有所不同:
1:
SELECT成本:0%
Table Scan成本:100%
 
2:
SELECT成本:5%
Table Scan成本:95%
 
 
 
Top 
 
 回覆人: pbsql(風雲) ( ) 信譽:106 2004-07-14 10:54:00 得分: 0 
 
 
  如果此時將數據全部刪除:truncate table test
 
然後再看回頭來看執行計劃,情況又會有所不同:
1:
SELECT成本:0%
Table Scan成本:100%
(似乎是說索引沒有用上)
2:
SELECT成本:0%
Bookmark Lookup成本:49%
test.IX_test_name Index Seek成本:51%
(會用到索引)
 
上面的情形有些解釋不通啊
 
 
Top 
 
 回覆人: lynx1111(任我行:一個PLMM看着就興奮的男人) ( ) 信譽:95  2004-07-14 10:55:00 得分: 0 
 
 
   你以前不是發了一個類似的貼嗎?
 
我相信SQL的執行計劃與數據表中數據的多少有關.
 
 
Top 
 
 回覆人: pbsql(風雲) ( ) 信譽:106 2004-07-14 10:56:00 得分: 0 
 
 
   那個與這個有區別
 
 
Top 
 
 回覆人: zonelive(peter) ( ) 信譽:99 2004-07-14 10:57:00 得分: 0 
 
 
   那只是一個估計值吧
 
 
Top 
 
 回覆人: laker_tmj(laker) ( ) 信譽:100 2004-07-14 11:32:00 得分: 0 
 
 
   up
 
 
Top 
 
 回覆人: wanyingsong(豌豆) ( ) 信譽:100 2004-07-14 11:38:00 得分: 0 
 
 
   學習ing!希望大家都寫一些好東西,讓小弟學習,呵呵
 
 
Top 
 
 回覆人: pbsql(風雲) ( ) 信譽:106 2004-07-14 12:02:00 得分: 0 
 
 
   執行計劃雖是一個估計值,但從中可以分析SQL SERVER是怎麼解析SQL語句並執行的,從而寫最優的SQL語句
 
現在這個執行計劃不定,怎麼去判斷怎樣最優?
 
 
Top 
 
 回覆人: leeboyan(★★寶寶★★) ( ) 信譽:100 2004-07-14 12:09:00 得分: 0 
 
 
   關注
 
 
Top 
 
 回覆人: brucely() ( ) 信譽:100 2004-07-14 12:21:00 得分: 0 
 
 
   長學問
 
 
Top 
 
 回覆人: zjcxc(鄒建) ( ) 信譽:343 2004-07-14 12:45:00 得分: 0 
 
 
   測測
 
 
Top 
 
 回覆人: zjcxc(鄒建) ( ) 信譽:343 2004-07-14 12:50:00 得分: 0 
 
 
   怎麼說呢,好像又是與條件相關
 
你把查詢語句換成:
select * from test where name='名稱0000000001'
 
結果又能利用上索引了.
 
 
Top 
 
 回覆人: zjcxc(鄒建) ( ) 信譽:343 2004-07-14 12:52:00 得分: 0 
 
 
   將條件換成<=,< 也一樣可以利用上索引
 
看來好像跟表中的數據又發生了關係.
 
 
Top 
 
 回覆人: zjcxc(鄒建) ( ) 信譽:343 2004-07-14 12:59:00 得分: 0 
 
 
   我看應該是這樣的
 
條件是:
name>'名稱0000000001'
的話,因爲'名稱0000000001'這是一個固定條件,所以可以根據表中的記錄情況,來確定是用索引快,還是直接掃描錶快
 
或者可以說,因爲你這是一個死條件,所以已經可以根據表中的現有記錄直接出方案了,所以是跟表中的記錄數有關.
 
 
而用變量的話,因爲變量的值是變化的,即使是按你測試的語句那樣,已經寫好了變量的值,SQL也會認爲是一個變化值,所以不能根據表中現有記錄確定算法,所以就用了另一種優化方法.
 
 
 
Top 
 
 回覆人: zjcxc(鄒建) ( ) 信譽:343 2004-07-14 13:01:00 得分: 0 
 
 
   --同樣的一萬條記錄,樓主還可以測試一下:
 
select * from test where name>'名稱9000000001'
 
select * from test where name<'名稱9000000001'
 
select * from test where name<'名稱0000000001'
 
這些的執行計劃都不一樣,所以應該是:
如果條件的值是固定的,則執行計劃的方案=條件+表中現有記錄的值
 
 
Top 
 
 回覆人: zjcxc(鄒建) ( ) 信譽:343 2004-07-14 13:03:00 得分: 0 
 
 
   也可以理解爲,條件中,使用固定值與使用變量值,SQL採用不同的算法來確定執行計劃
 
 
 
Top 
 
 回覆人: pbsql(風雲) ( ) 信譽:106 2004-07-14 13:07:00 得分: 0 
 
 
   拋開用變量的那句不看,就看1:
爲什麼在沒有數據和數據只有100條的情況下能用上索引,而在10000條時就用不上索引呢?
而在數據爲10000條時若執行了truncate table test,似乎還是說索引沒有用上,又怎麼解釋呢?
 
 
Top 
 
 回覆人: zjcxc(鄒建) ( ) 信譽:343 2004-07-14 13:13:00 得分: 0 
 
 
   只能這樣解釋,因爲不用索引比用索引快
 
 
Top 
 
 回覆人: pbsql(風雲) ( ) 信譽:106 2004-07-14 13:18:00 得分: 0 
 
 
   好象不能這樣解釋吧,那豈不成了:數據少時(100條)用索引比不用索引快,數據多時(10000條)不用索引比用索引快?
 
 
Top 
 
 回覆人: zjcxc(鄒建) ( ) 信譽:343 2004-07-14 13:19:00 得分: 0 
 
 
   怪事了,我現在第二種方法也不用索引了.
 
 
Top 
 
 回覆人: outwindows(窗外) ( ) 信譽:101 2004-07-14 13:21:00 得分: 0 
 
 
   mark...
 
 
Top 
 
 回覆人: zjcxc(鄒建) ( ) 信譽:343 2004-07-14 13:24:00 得分: 0 
 
 
   --有點說不清楚,1萬條記錄的時候,這個一樣不能利用索引.
 
declare @id varchar(20)
set @id='名稱0000005001'
select * from test where name>@id
 
 
Top 
 
 回覆人: zjcxc(鄒建) ( ) 信譽:343 2004-07-14 13:25:00 得分: 0 
 
 
   --就改這麼一點點,索引也用不上.
 
declare @id varchar(20)
set @id='名稱0000000002'
select * from test where name>@id
 
 
Top 
 
 回覆人: zjcxc(鄒建) ( ) 信譽:343 2004-07-14 13:28:00 得分: 0 
 
 
   用變量的方式,測試了幾個臨界值及中間值,似乎就 名稱0000000001 的時候使用索引,其他都沒有
 
 
Top 
 
 回覆人: pbsql(風雲) ( ) 信譽:106 2004-07-14 13:34:00 得分: 0 
 
 
   我的測試結果:(數據10000條)
用=時,1、2都能用上索引
用>、>=時,1、2都不能用上索引
用<、<=時,1能用上索引,2不能用上索引
 
真的是沒法解釋
 
 
Top 
 
 回覆人: i9988(冒牌j9988 V0.1) ( ) 信譽:100 2004-07-14 13:56:00 得分: 0 
 
 
   我簡單說說我的理解:
1、索引的實際操作比我們一般理解的複雜,索引的選用與否與查詢條件、數據多少、數據值(關鍵值)的分佈、索引字段的長度、是否有聚集索引、聚集索引字段的長度(如果有聚集索引)都有關。因爲索引是否選用在默認情況下是自動的。
2、我們一般都能理解查詢條件對索引是否選用的影響,這裏不多說了。
3、要說其他方面,首先要理解數據頁的概念,簡單地說,不管數據還是索引都是放在8k(7.0版本以上)或者2k(7.0版本以下)爲單位的頁裏,我假設大家都理解數據頁的概念。
4、數據多少的影響主要是這樣的,當數據比較少,極端的是都在一個頁裏,這樣全表掃描只訪問一個頁,而通過索引至少訪問兩個頁,用索引的速度顯然不如全表掃描。而數據多的時候,通過索引放問怎麼比全表掃描快,相信大家都是理解的。
5、數據值(關鍵值)的分佈
   要說這個就要說索引的結構了,只說2k版本(不同版本有所不同),是 B 樹結構,B 樹結構在這裏很難說得清楚,乾脆當大家都是理解的。
   數據值(關鍵值)的分佈主要的影響是可能使得B 樹結構不再均衡,可能偏了,造成對不同鍵值的訪問,都頁的次數不同,速度也就有所差別,但是一般影響不大,但是如果向樓上幾位只測試很少數據的情況,可能影響就大了。
6、索引字段的長度
   因爲頁的大小固定,索引字段的長度越大,沒頁放的索引行就越少,索引的層數(B樹的深度)就越大,需要訪問的頁數頁就越多了。
7、是否有聚集索引
   這個和非聚集索引的結構有關,如果有聚集索引,非聚集索引的索引行可能存放聚集索引的鍵值,否則,只能存放數據行的指針。因爲聚集索引是按順序存放的,前者的速度比後者快很多。
8、聚集索引字段的長度(如果有聚集索引)
   由於有第7點和第6點,聚集索引字段的長度可能尤爲重要,所以設計表的時候,聚集索引最好建立在儘可能短的字段上。
9、這裏都是做簡單的理解,數據庫內部實際運作比這個理解複雜。
10、影響的因素還有很多,比如聚集索引是否唯一、組合索引的字段順序等,本人理解有限,沒辦法都解釋清楚。
 
 
 
 
 
 
Top 
 
 回覆人: pbsql(風雲) ( ) 信譽:106 2004-07-14 14:02:00 得分: 0 
 
 
   多謝J老師,慢慢體會
 
 
Top 
 
 回覆人: i9988(冒牌j9988 V0.1) ( ) 信譽:100 2004-07-14 14:03:00 得分: 0 
 
 
   哈哈,冒牌成真了?
 
別看錯了
 
 
 
Top 
 
 回覆人: Limperator(珊兒) ( ) 信譽:97 2004-07-14 14:06:00 得分: 0 
 
 
  1.
select * from test(index=IX_test_name) where name>'名稱0000000001'
go
2.
declare @id varchar(20)
set @id='名稱0000000001'
select * from test(index=IX_test_name) where name>@id
go
 
 
試試上面兩句, 和數據量還有沒有關係?
 
 
Top 
 
 回覆人: zjcxc(鄒建) ( ) 信譽:343 2004-07-14 14:19:00 得分: 0 
 
 
   強制指定索引已經超出了本帖的討論範圍
 
本帖討論的是SQL的執行計劃與數據量的關係的問題.
 
強制指定索引已經指明瞭如何使用索引,所以有點偏題
 
 
Top 
 
 回覆人: pbsql(風雲) ( ) 信譽:106 2004-07-14 17:36:00 得分: 0 
 
 
   是的,本帖討論SQL的執行計劃與數據量的關係
 
 
Top 
 
 回覆人: longtusoft(神燈之主) ( ) 信譽:100 2004-07-15 07:41:00 得分: 0 
 
 
   摟主的信譽爲什麼是106呀?
 
 
Top 
 
 回覆人: Lwg0901(傷心人) ( ) 信譽:100 2004-07-15 08:08:00 得分: 0 
 
 
   爲什麼csdn的加入收藏夾用不了了呢?
 
鬱悶。。。很多好帖都不能收藏。。。
 
 
 
Top 
 
 回覆人: dotbyte() ( ) 信譽:100 2004-07-15 08:20:00 得分: 0 
 
 
   mark
 
 
Top 
 
 回覆人: zheninchangjiang(徐震&gt;願母親安息) ( ) 信譽:100 2004-07-15 08:22:00 得分: 0 
 
 
   不理解
 
 
Top 
 
 回覆人: prcgolf(小鳥) ( ) 信譽:99 2004-07-15 09:27:00 得分: 0 
 
 
   UP
 
 
Top 
 
 回覆人: meilian01(meilian) ( ) 信譽:100 2004-07-15 09:54:00 得分: 0 
 
 
   學習
  
 
Top 
 
 回覆人: pcyy(媽媽我愛你) ( ) 信譽:100 2004-07-15 09:57:00 得分: 0 
 
 
   UP
 
 
 
Top 
 
 回覆人: flyincs(我想回家……) ( ) 信譽:100 2004-07-15 13:12:00 得分: 0 
 
 
   學習
 
 
Top 
 
 回覆人: futulove(福途£愛) ( ) 信譽:100 2004-07-15 13:37:00 得分: 0 
 
 
   學習
頂一下
 
 
Top 
 
 回覆人: panpass(潘帕斯草原的雄鷹) ( ) 信譽:100 2004-07-15 17:28:00 得分: 0 
 
 
   學習
 
 
Top 
 
 回覆人: wgh166(涌金水牛) ( ) 信譽:100 2004-07-15 19:51:00 得分: 0 
 
 
   up
 
 
Top 
 
 回覆人: YiYanXiYin(NullComeFullBack) ( ) 信譽:101 2004-07-15 20:33:00 得分: 0 
 
 
   哇!效率就是這樣產生的!
 
 
Top 
 
 回覆人: YiYanXiYin(NullComeFullBack) ( ) 信譽:101 2004-07-15 20:34:00 得分: 0 
 
 
   順便問一下:成本是怎樣得出來的?
 
 
Top 
 
 回覆人: pascal21(犬夜叉) ( ) 信譽:100 2004-07-15 21:40:00 得分: 0 
 
 
   數據庫技術QQ羣:2966104
數據庫技術QQ羣:2966104
數據庫技術QQ羣:2966104
數據庫技術QQ羣:2966104
 
 
 
 
Top 
 
 回覆人: yzqyzq(山羊) ( ) 信譽:100 2004-07-15 22:24:00 得分: 0 
 
 
   學習!
 
 
Top 
 
 回覆人: tx1icenhe(冒牌馬可 V0.1) ( ) 信譽:100 2004-07-20 10:18:00 得分: 0 
 
 
  
 
 
 
Top 
 
 回覆人: wanyingsong(豌豆) ( ) 信譽:100 2004-07-20 10:35:00 得分: 0 
 
 
   有一個表,列有SEQ_NO INT 主鍵 建立了聚集索引,FINANCE_YEAR INT,FINANCE_MONTH,.....,又建立了索引(fiannce_year,finance_month),表裏面有27萬條記錄
爲什麼了我在查詢分析器裏面執行
select * from a_store_recent_month where finance_year=2003 and finance_month=4
執行計劃使用的卻沒有使用到finance_year,finance_month的索引呢?
 
 
Top 
 
 回覆人: pbsql(風雲) ( ) 信譽:106 2004-07-20 11:15:00 得分: 0 
 
 
   不要完全相信執行計劃
 
 
Top 
 
 回覆人: wanyingsong(豌豆) ( ) 信譽:100 2004-07-20 11:21:00 得分: 0 
 
 
   但是確實是沒有用到finance_year,finance_month索引呀,我測試了一下
select * from a_store_recent_month(index=IDX_RECMON_FYEARMONTH) where finance_year=2003 and finance_month=4
select * from a_store_recent_month where finance_year=2003 and finance_month=4
就要快很多
 
 
Top 
 
 回覆人: outwindows(窗外) ( ) 信譽:101 2004-07-20 11:25:00 得分: 0 
 
 
   mark...
 
 
Top 
 
 回覆人: pbsql(風雲) ( ) 信譽:106 2004-07-20 11:32:00 得分: 0 
 
 
   所以說SQL的下個版本可能會要求指定index了
 
 
Top 
 
 回覆人: pjy(古蟲) ( ) 信譽:100 2004-07-20 11:49:00 得分: 0 
 
 
   是有些奇怪!
我使用摟主的例子,在10000條記錄中執行查詢
開始兩個語句都是
select 成本6%
table scan成本94%
 
連續執行幾遍,
語句2的成本沒有變,
但語句1的成本變成
SELECT成本:0%
Bookmark Lookup成本:49%
test.IX_test_name Index Seek成本:51%
(會用到索引)
 
 
Top 
 
 回覆人: CSDMN(冒牌經理 V0.1) ( ) 信譽:100 2004-07-20 11:51:00 得分: 0 
 
 
   實際的速度還跟緩存有關
 
 
 
Top 
 
 回覆人: pbsql(風雲) ( ) 信譽:106 2004-07-20 11:59:00 得分: 0 
 
 
   但是爲什麼對於同一個語句,=、>、>=、<、<=在索引使用上會有差別?
 
 
Top 
 
 回覆人: pjy(古蟲) ( ) 信譽:100 2004-07-20 12:00:00 得分: 0 
 
 
   實際上SQL SERVER查詢分析器選擇查詢策略時會根據索引統計,我猜想語句1因爲寫死了查詢的匹配值,所以在執行後,SQL SERVER自動記錄了該值的索引統計匹配記錄數;而制定變量的化,SQL SERVER使用了缺省的估計值('>'使用的是33%)
 
 
Top 
 
 回覆人: pjy(古蟲) ( ) 信譽:100 2004-07-20 13:11:00 得分: 0 
 
 
   看查詢分析器的查詢策略,語句1的預計行計數爲30,語句2的爲3000!
 
很奇怪,對於這個表的兩條語句的查詢,我感覺table scan應該比用索引還快一些呀!匹配行太多了!table scan 只需要大約33頁,索引需要的開銷大多了呀!
奇怪!
 
 
Top 
 
 回覆人: pjy(古蟲) ( ) 信譽:100 2004-07-20 13:45:00 得分: 0 
 
 
   我測試了,實際上查詢分析器顯示的查詢策略並不完全正確!
我使用
print convert(char(30),getdate(),109)
select * from test where name>'名稱0000000001'
go
print convert(char(30),getdate(),109)
declare @id varchar(20)
set @id='名稱0000000001'
print convert(char(30),getdate(),109)
select * from test where name>@id
go
print convert(char(30),getdate(),109)
declare @id varchar(20)
set @id='名稱0000000001'
select * from test where name=@id
go
print convert(char(30),getdate(),109)
執行信息:
07 20 2004 1:19:45:780PM    
 
(所影響的行數爲 9999 行)
 
07 20 2004 1:19:45:827PM    
07 20 2004 1:19:45:827PM    
 
(所影響的行數爲 9999 行)
 
07 20 2004 1:19:45:890PM    
 
(所影響的行數爲 1 行)
 
07 20 2004 1:19:45:890PM 
 
---------------------------------
語句1使用了47毫秒,語句2使用了63毫秒!
 
而使用
print convert(char(30),getdate(),109)
select * from test(index = IX_test_name) where name>'名稱0000000001'
go
print convert(char(30),getdate(),109)
declare @id varchar(20)
set @id='名稱0000000001'
print convert(char(30),getdate(),109)
select * from test(index = IX_test_name) where name>@id
go
print convert(char(30),getdate(),109)
declare @id varchar(20)
set @id='名稱0000000001'
select * from test where name=@id
go
print convert(char(30),getdate(),109)
執行信息:
07 20 2004 1:32:22:653PM    
 
(所影響的行數爲 9999 行)
 
07 20 2004 1:32:22:700PM     
07 20 2004 1:32:22:700PM    
 
(所影響的行數爲 9999 行)
 
07 20 2004 1:32:22:763PM    
 
(所影響的行數爲 1 行)
 
07 20 2004 1:32:22:763PM    
------------------------
語句1使用了47毫秒,語句2使用了63毫秒
 
感覺兩個語句,SQL SERVER在執行時都用到了索引!
(感覺sql server 2000的查詢分析器提供的很多數據都不太準確,多次執行的數據不太一致,不如以前6.5版本的查詢分析器詳細。以上數據取的是穩定時的結果)
 
 
Top 
 
 回覆人: mophi(追球) ( ) 信譽:99 2004-07-20 14:32:00 得分: 0 
 
 
   我的測試是:100條時不管理用那種方法都用索引了
但10000條時不管理用那種方法都不用索引了
 
 
 
Top 
 
 回覆人: pjy(古蟲) ( ) 信譽:100 2004-07-20 14:38:00 得分: 0 
 
 
   WO!
怎麼測試結果都不同呀!
 
 
Top 
 
 回覆人: solidpanther(╃╄╃我愛機器貓╄╃╄) ( ) 信譽:100 2004-07-20 14:50:00 得分: 0 
 
 
   收藏!
 
 
Top 
 
 回覆人: yzqyzq(山羊) ( ) 信譽:100 2004-07-20 18:23:00 得分: 0 
 
 
   前幾天做了上面的實驗。最後從結論上來看SQL的執行計劃與數據表中數據的多少有關好象是不對的。
/*--數據
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[test]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
 drop table test
go
--建表
create table test(id varchar(10) not null,name varchar(20) not null) on [PRIMARY]
go
--建主鍵、索引
ALTER TABLE test ADD CONSTRAINT PK_test PRIMARY KEY NONCLUSTERED (id) ON [PRIMARY]
CREATE INDEX IX_test_name ON test(name) ON [PRIMARY]
go
 
問題:對於上面這樣一個表,下面的查詢語句是否有區別?
1.
select * from test where name>='名稱0000000001'
go
2.
declare @id varchar(20)
set @id='名稱0000000001'
select * from test where name>@id
go
*/
這個是和索引有關係的不是說它的條件固定不固定
 
索引就好比我們看書一樣,如果我們看的東西比較零散,
跳躍性比較大時使用目錄是比較好的,
一看書的目錄就可定位到要找的東西,不用一頁一頁翻。
對於
select * from test where name>='名稱0000000001'語句使用索引反到不如全表掃描快
但是對於下面的語句就可以使用索引了。
 
select * from test where name in(select name from test where name like '%9')
它的跳躍性比較大,使用索引查詢更快一些。
一般數據庫會根據查詢的條件選擇相應的策略。
比如oracle數據庫如果查詢總數據的20%以下自動會使用到索引,如果大於20%會全表掃描。
 
 
Top 
 
 回覆人: pbsql(風雲) ( ) 信譽:106 2004-07-20 18:26:00 得分: 0 
 
 
   對於同一個語句,=、>、>=、<、<=在索引使用上會有差別又怎麼解釋?
 
 
Top 
 
 回覆人: yzqyzq(山羊) ( ) 信譽:100 2004-07-20 18:35:00 得分: 0 
 
 
   同時可以比較下面的這些語句:
使用到索引
select * from test where name>='名稱0000000001' and name<='名稱0000000002'
 
select * from test where name>='名稱0000000001' and name<='名稱0000000031'
未使用索引
 
select * from test where name>='名稱0000000001' and name<='名稱0000000032'
這些我們都可以好好體會SQLserver的SQL語句的執行路線。
 
 
 
Top 
 
 回覆人: yzqyzq(山羊) ( ) 信譽:100 2004-07-20 18:47:00 得分: 0 
 
 
  
 從上面可以看出SQLserver對於是使用索引還是全表掃描,有一定的算法,這個是根據所查數據在總數據所佔的比例。
 
 
Top 
 
 回覆人: prcgolf(小鳥) ( ) 信譽:99 2004-07-21 10:23:00 得分: 0  
 
 
   up
 
 
Top 
 
 回覆人: evafly920() ( ) 信譽:100 2004-07-21 14:05:00 得分: 0 
 
 
   mark
 
 
Top 
 
 回覆人: pjy(古蟲) ( ) 信譽:100 2004-07-22 10:02:00 得分: 0 
 
 
   sql server對於'=','<','>'本身有一個缺省的匹配值,'>'和'<'默認的是33%
也有一套關於利用索引或表掃描的算法。
 
對於樓主的兩條執行語句,我分析是表掃描要快的多,只需要大約33個數據頁的開銷!比33%的匹配率下的索引都應該快。SQL SERVER應該會選擇表掃描的!
 
但實際執行後顯示的數據確不是那麼回事!
以前6.5的查詢分析器可以看到詳細的執行策略及I/O消耗,現在2000的好象看不到了!
鬱悶!
 
 
Top 
 
 回覆人: pjy(古蟲) ( ) 信譽:100 2004-07-22 10:10:00 得分: 0 
 
 
   使用select * from test where name='名稱0000000001'
SQL SERVER肯定是用到索引了!
 
但是如果用變量代替'名稱0000000001',SQL SERVER會認爲有10%的匹配率(因爲該列值並沒有限制爲唯一),所以我感覺也不一定就會用到索引!它會比較各種情況的效率
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章