TOP 1比不加TOP慢的疑惑

2021-08-29 13:10:46 字數 4717 閱讀 6426

問題描述:

有乙個查詢如下,去掉top 1的時候,很快就出來結果了,但加上top 1的時候,一般要2~3秒才出資料,何解?

select

top 1

a.invno

from

a, b

where

a.item = b.itemnumber

and b.ownercompanycode is

notnull

問題原因分析:

在使用top 1的時候,sql server會盡力先找出這條top 1的記錄,這就導致它採用了與不加top時不一致的掃瞄演算法,sql server查詢優化器始終認為,應該可以比較快的找到匹配的第1條記錄,所以一般是使用巢狀迴圈的聯接,則不加top 1時,sql server會根據結構和資料的統計資訊決策出聯接策略。巢狀迴圈一般適用於聯絡的兩個表,乙個表的資料較大,而另乙個表的資料較小的情況,如果查詢匹配的值出現在掃瞄的前端,則在取top 1的情況下,是符合巢狀迴圈聯絡的使用條件的,但當匹配的資料出現在掃瞄的後端,或者是基本上沒有匹配的資料時,則巢狀迴圈要掃瞄完成兩個大表,這顯然是不適宜的,也正是因為這種情況,導致了top 1比不加top 1的效率慢很多

關於此問題的模擬環境:

use

tempdb

gosetnocount

on--***********************************===

--建立測試環境

--***********************************===

raiserror

('建立測試環境'

,10, 1)

with nowait

-- table a

create

table [dbo].a(

[trannumber] [int] identity

(1, 1)

notnull,

[invno] [char](8)

notnull,

[item] [char](15)

null

default(''

),primary

key([trannumber]))

create

index [indexoninvno] on [dbo].a([invno])

create

index [indexonitem] on [dbo].a ([item])

create

index [indexoniteminnvo] on [dbo].a([invno], [item])

go

-- table b

create

table [dbo].b(

[itemnumber] [char](15)

notnull

default(''

),[companycode] [char] (4)

notnull,

[ownercompanycode] [char](4)

null,

primary

key([itemnumber], [companycode]))

create

index [itemnumber] on [dbo].b([itemnumber])

create

index [companycode] on [dbo].b([companycode])

create

index [ownercompanycode] on [dbo].b([ownercompanycode])

go

--***********************************===

--生成測試資料

--***********************************===

raiserror

('生成測試資料'

,10, 1)

with nowait

insert

[dbo].a([invno], [item])

select

left(

newid

(), 8),

right(

newid

(), 15)

from

syscolumns a, syscolumns b

insert

[dbo].b([itemnumber], [companycode], [ownercompanycode])

select

right(

newid

(), 15),

left(

newid

(), 4),

left(

newid

(), 4)

from

syscolumns a, syscolumns b

go

速度測試指令碼:

--***********************************===

--進行查詢測試

--***********************************===

raiserror

('進行查詢測試'

,10, 1)

with nowait

declare

@dt datetime

, @id int

, @loop int

declare

@ table

(id int

identity

,[top 1] int

,[without top] int)

set@loop = 0

while

@loop 10

begin

set @loop = @loop + 1

raiserror

('test %d'

, 10, 1, @loop)

with nowait

set @dt =

getdate

()select

top 1

a.invno

from a, b

where a.item = b.itemnumber

and b.ownercompanycode is

notnull

insert @([top 1])

values

(datediff

(ms, @dt,

getdate

()))

select @id =

scope_identity

(), @dt =

getdate

()select

--top 1

a.invno

from a, b

where a.item = b.itemnumber

and b.ownercompanycode is

notnull

update @ set [without top] =

datediff

(ms, @dt,

getdate

())where id = @id

endselect

*from @

union

allselect

null,

sum([top 1]),

sum([without top])

from @

go

測試資料的變更指令碼:

declare

@value char

(15), @value1 char

(15)

select

@value =

left(

newid

(), 15),

@value1 =

left(

newid

(), 15)

update

a

setitem =@value

froma

inner

join(

select

top 1

[trannumber]

from

(select

top20percent

[trannumber]

from a

order

by [trannumber]

)aaorder

by [trannumber] desc

)b

on a.[trannumber] = b.[trannumber]

update

b

setitemnumber = @value

fromb

inner

join(

TOP 1比不加TOP慢的疑惑

問題描述 有乙個查詢如下,去掉top 1的時候,很快就出來結果了,但加上top 1的時候,一般要2 3秒才出資料,何解?select top 1 a.invno from a,b where a.item b.itemnumber and b.ownercompanycode is notnull ...

Pytorch實現Top1準確率和Top5準確率

之前一直不清楚top1和top5是什麼,其實搞清楚了很簡單,就是兩種衡量指標,其中,top1就是普通的accuracy,top5比top1衡量標準更 嚴格 具體來講,比如一共需要分10類,每次分類器的輸出結果都是10個相加為1的概率值,top1就是這十個值中最大的那個概率值對應的分類恰好正確的頻率,...

計算機視覺中的top 1和top 5

imagenet imagenet 專案是乙個用於物體物件識別檢索大型視覺資料庫。截止2016年,imagenet 已經對超過一千萬個影象進行手動注釋,標記影象的類別。在至少一百萬張影象中還提供了邊界框。自2010年以來,imagenet 舉辦一年一度的軟體競賽,叫做 imagenet large ...