目錄
- RowIterator
- Init()
- Read()
- SetNullRowFlag()
- UnlockRow()
- StartPSIBatchMode()
- EndPSIBatchModeIfStarted()
- real_iterator()
RowIterator
使用選定的訪問方法讀取單個表的上下文:索引讀取,掃描等,緩存的使用等。
它主要是用作接口,但也包含一些私有成員函數,這些函數對于許多實現都是有用的,例如錯誤處理。
RowIterator是一個簡單的迭代器。您對其進行初始化,然后一次讀取一個記錄,直到Read()返回EOF。如果需要,RowIterator可以從其他Iterators讀取數據,例如SortingIterator,它從另一個RowIterator接收記錄并對其進行排序。
抽象并不完全緊密。特別是,它仍然留給TABLE一些細節,例如要讀取的列(read_set)。這意味著可能很難對兩個表的聯接進行排序。
使用方法:
unique_ptr<RowIterator> iterator(new ...);
if (iterator->Init())return true;
while (iterator->Read() == 0) {...
}
Init()
初始化或重新初始化迭代器。
在嘗試Read()之前,必須始終調用Init()(但是Init()并不意味著Read())。
您可以多次調用Init();隨后的調用將使迭代器倒回(或重新定位,具體取決于迭代器是否采用TABLE_REF),并允許您重新讀取記錄。
Read()
讀一行。
該行數據實際上不是從函數返回的;它被放在表的記錄緩沖區中(如果有連接,則放在表中),即table-> records [0]。
SetNullRowFlag()
將當前行緩沖區標記為包含或不包含NULL行,這樣,如果您從中讀取并且標志為true,則無論緩沖區中實際上有什么(通常是一些舊的剩余行),您都只會得到NULL。
當迭代器沒有產生任何行并且我們需要產生一個NULL補充行時,它用于外部聯接。Init()或Read()不一定會重置此標志,因此,如果您將其設置為true,請確保在需要時也將其設置為false。
注意,可以在不首先調用Init()的情況下調用它。
UnlockRow()
在一些特定的查詢中,比如SELECT FOR UPDATE, UPDATE or DELETE查詢,正在讀取的行將在上面上鎖。這意味著鎖的設置取決于優化器是否選擇了一個表掃描或者使用索引。
但是在某些事務隔離級別下(讀取或提交),當且僅當行因為WHERE這個謂詞失敗,只有返回的行受到保護,那些沒有返回的行就不會受到保護了。
所以如果Read()返回一行數據,如果不使用它,就應該Read()之后調用UnlockRow(),它將允許存儲引擎在這種情況下釋放行鎖。
StartPSIBatchMode()
啟動性能模式批處理模式。
PFS批處理模式可以減輕性能模式的開銷,該性能模式通常應用于整個聯接的最內表。
如果在掃描表之前先啟動它,然后再結束它,則整個處理程序調用集將作為一組,并且成本將平均分配。這樣可以減少計時器開銷。
如果啟動PFS批處理模式,則還必須注意在掃描結束時以一種另一種方式結束它。請注意,即使查詢突然結束(達到LIMIT或者發生錯誤),也必須結束它。最簡單的解決方法就是在掃描結束時在根迭代器上簡單調用EndPSIBatchModeIfStarted()。
開始批處理和結束的規則是:
1、如果迭代器只有一個子類,則將所有StartPSIBatchMode()的調用轉發給它。
2、如果驅動迭代器(使用for循環或者類似的方法讀取行),需要使用PFSBatchMode
3、如果迭代器有多個子類,忽略StartPSIBatchMode()的調用,并且根據需要自行處理批處理模式
所以,在掃描單個表時,通常會為該表激活批處理模式,因為我們在根迭代器上調用該函數,并且一直向下傳入表迭代器。但是調用后,該調用將被忽略,并且迭代器需要根據需要自行激活批處理模式。
EndPSIBatchModeIfStarted()
結束性能模式批處理模式
具有子級的迭代器(復合迭代器)必須將該函數調用轉發給所有子迭代器。這樣可以確保在對根迭代器進行這樣的調用之后,所有處理程序都退出批處理模式。
real_iterator()
如果該迭代器包裝了其他迭代器,需要將該迭代器向下轉換為特定的迭代器類型。