sql server使用掃瞄(scan)和查詢(seek)這兩種演算法從資料表和索引中讀取資料。這兩種演算法構成了查詢的基礎,幾乎無處不在。scan會掃瞄並且返回整個表或整個索引。 而seek則更有效率,根據謂詞(predicate),隻返索引內的乙個或多個範圍內的資料。下面將以如下的查詢語句作為例子來分析scan和seek:
select orderdate from orders where orderkey = 2
使用scan的方式,sql server 會去讀取orders表中的每一行資料,讀取的時候評估是否滿足謂詞 「where order=2」。如果滿足(資料行符合條件),則返回該行。這個例子裡,我們將這個謂詞稱作「residual predicate」。為了得到最優的效能,sql會盡可能地在掃瞄中使用「residual predicate」。但如果residual predicate的開銷過於昂貴,sql server可能會使用單獨的「filter iterator」. 「residual predicate」以where關鍵字的形式出現在文字格式的plan中。對xml格式的plan,則是標記的形式。
下面這個掃瞄的文字格式的plan的結果:
|–table scan(object:([orders]), where:([orderkey]=(2)))
下圖說明了掃瞄的方式:
無論資料行是否滿足條件,掃瞄的讀取方式都會訪問表中的每乙個資料,所以scan的成本和表的資料總量是成比例的。 因此,如果表很小或者表內的大多數資料多滿足謂詞,scan是一種有效率的讀取方式。然而如果表很大或者絕大多數的資料並不滿足謂詞, 那麼這種方式會讓我們訪問到太多不需要的資料頁面,並執行更多的額外的io操作。
繼續以上面的查詢為例子,如果在orderkey列上有乙個索引,那麼seek可能會是乙個好的選擇。使用seek的訪問方式,sql server會使用索引直接導向到滿足謂詞條件的資料行。 這個例子裡,我們將這個謂詞稱為「seek predicate」。 大多數情況下,sql server不必將「seek predicate」重新評估為「residual predicate」。 索引會保證「seek」只返回符合條件的資料行。「seek predicate」以seek關鍵字的形式出現在文字格式的plan中。 對於xml 格式的plan,則以標記出現。
下面是使用seek的文字格式的plan的結果:
|–index seek(object:([orders].[okey_idx]), seek:([orderkey]=(2)) ordered forward)
使用seek時,sql server只會直接訪問到滿足條件的資料行和資料頁,因此它的成本只跟滿足條件的資料行的及其相應的資料頁面數量成比例,
和基表的資料量完全沒有關係。因此,如果對於乙個選擇性很高(通過這個謂詞,可以篩選掉表中的大部分資料)的謂詞條件,seek是非常高效的。
下面的**列出了seek和scan這兩種查詢方式和堆表,聚簇索引和非聚簇索引的各種組合:
scan
seek
heap
table scan
clustered index
clustered index scan
clustered index seek
non-clustered index
index scan
index seek
tags
index scan
index seek
table scan
redis中keys和scan的對比
redis中keys和scan的對比 兩者都是用來返回key的,但是使用場景和方法不同。一 keys keys pattern 比如 keys keys user info 特點 1 在選定的庫中,一次性全部返回符合條件的key,如果資料量很大將會等待很久,因此,只適合用在可控的量小的鍵查詢,比如幾...
理解redis中的scan
redis在2.8版本提供了scan相關命令用來遍歷集合中的元素。和keys,smembers命令遍歷大集合場景下會阻塞redis一定時間不同,scan命令每次遍歷只會返回一定數量集合元素和當前的遍歷位置的游標,時間非常短,不會阻塞redis,遍歷大集合時對其他業務影響較小。缺點是通過多次呼叫sca...
Theano中scan函式的使用
theano作為深度學習領域乙個經典的python庫,可以先定義數學表示式再進行運算,開創了符號計算的先河。最近在科研過程中用到了其中的scan 函式,雖然以前也學過這個框架,但是tensorflow永久了,感覺就把一些知識點忘記了,於是想到了寫筆記的重要性,故在這裡記錄下來,以備隨時回頭翻看。在學...