2013-03-09 90 views
9

我知道在MongoDB查詢上使用.explain()的輸出,可以查看nnscanned之間的差異,以確定是否已執行完整集合掃描,或者是否使用了索引。 The docs狀態如何確定是否已在MongoDB中完成完整集合掃描

想要nnscanned的值儘可能接近。

Kyle Banker's excellent book MongoDB in Action說非常類似的東西:

一般來說,你想要的nnscanned值是接近在一起越好。在進行收集掃描時,幾乎從未如此。

很顯然,這兩種說法都沒有將nnscanned作比較。多少比例的差異通常會推斷全面的收集掃描 - 10%,20%,30%+?有沒有其他方法可以檢查完整的收集掃描是否已完成?

回答

6

什麼比例的差異通常推斷完整的收集掃描 - 10%,20%,30%+?

這是不可能說的,但如果它真的重要整個噸,那麼你可能會看到一個平均發現高達200%的性能下降;所以是的,你會注意到它。這很像這方面的其他數據庫。

是否有任何其他方法來檢查是否已完成完整的集合掃描?

你可以用一個標誌,告訴它永遠不會做全表掃描,在這種情況下,它會嘗試時,它會拋出一個異常啓動的MongoDB到:http://docs.mongodb.org/manual/reference/mongod/#cmdoption-mongod--notablescan

但是最好的方式就是到在這裏使用explain,您將知道查詢何時不使用索引,並且被迫從磁盤或內存中掃描整個集合。

+1

結果但有可能爲查詢使用索引和仍然執行完整的收集掃描? – br3w5 2013-03-09 21:32:40

+2

@ssbrewster不,它不是,但是,高性能地使用索引是另一件需要確保的事情,使用索引和使用索引正確的方式是兩個不同的事情 – Sammaye 2013-03-09 21:37:37

+0

即使索引是隻用於排序結果? – br3w5 2013-03-09 21:54:15

1

確定性答案位於explain()輸出的第一行。

如果它說光標類型是「BasicCursor」,那麼它是一個簡單的集合掃描。

否則它會說它使用了什麼類型的索引和索引的名稱I.e. 「BtreeCursor id

查看文檔在這裏:http://docs.mongodb.org/manual/reference/explain/#explain-output-fields-core爲相同的解釋。

+0

但是正如我上面所問,可能滿如果索引僅用於排序結果,集合掃描仍然會發生? – br3w5 2013-03-09 22:25:28

+2

@ssbrewster如果你在'b'上做一個索引,然後做:'db.col.find({a:1})。sort({b:1});'然後我看不到它是如何的不會做全表掃描,但是是的 – Sammaye 2013-03-09 22:30:45

+0

@Sammaye謝謝你的意思...然後回到n vs nscanned的東西,那麼如果我看到兩者之間有30%-40%的差異,我想可以說已經完成了一個完整的集合掃描......並且它只是打了我一下可以通過在集合上運行count()並與nscanned進行比較來驗證這一點 - 正確嗎? – br3w5 2013-03-09 22:36:46

24

上面的答案並不完全正確。

集合掃描也會在索引用於排序但不能幫助匹配條件的情況下執行。在這種情況下,將掃描所有文檔(按索引順序)以查找與查找條件相匹配的文檔。另一種可能性是可能存在部分集合掃描,其中索引能夠根據一個或多個查找標準來縮小文檔的子集,但仍需要掃描該文檔子集以找到完整查找條件的匹配。

在這些情況下,解釋將顯示正在使用的索引而不是BasicCursor。因此,儘管在解釋中出現BasicCursor指示正在執行收集掃描,但缺少它並不意味着收集掃描未執行。

此外,使用--notablescan也不會幫助索引用於排序的位置。因爲查詢只會在不使用索引的情況下引發異常。它不會查找索引是用於比賽還是排序。

確定是否執行集合掃描的唯一一種萬無一失的方法是將索引鍵與查詢中的匹配條件進行比較。如果由查詢優化器(並在解釋中顯示)選擇的索引不能夠回答查詢匹配條件(即不同的字段),則需要收集掃描。

+0

MongoDB不會對索引排序執行集合掃描,mongodb會返回索引中文檔的順序,除非索引不存在,在這種情況下,它會在內存中執行集合掃描,scanandorder然後返回這些文檔 – Sammaye 2014-01-08 17:51:04

+0

如果您曾經有過這種情況,你會發現99%的時間你實際上scanandorder是真實的,這意味着該索引不用於排序 – Sammaye 2014-01-08 17:55:24

+3

你似乎只考慮排序匹配查找的情況。如果你有一個只支持排序的索引,並且你也與一個查找匹配,那麼這個索引被用於排序(索引通過運行以獲得排序順序),但是文檔仍然被掃描/讀取以便執行比賽。以{a:1,b:1}形式的文檔爲例,{{:1}}上的索引,但是一個查找語句db.test.find({b:1})。sort({a:1}) 。當b上沒有索引時,{a:1}索引用於排序,但集合仍然完整掃描。 – Matt 2014-01-08 22:48:37

0

嚴格看來,只有當光標是基本光標時纔會執行全表掃描。

如果存在btree遊標,那麼可能仍然有效地執行全表掃描來查找記錄,該btree索引僅用於排序。儘管如此,如果查看解釋的輸出結果,您是否真的可以確定它是全表掃描,而不用去計算記錄並查看存在的索引。

在問題的上下文中,如果查詢效率不高並且需要更好的索引或者應該暗示,那麼什麼是明確的。

0

您可以檢查(從MongoDB的文檔)的解釋的階段:

階段是描述性的操作;例如

-COLLSCAN爲集合掃描
-IXSCAN掃描索引鍵
-FETCH檢索文檔
-SHARD_MERGE用於合併從碎片