當前位置:成語大全網 - 書法字典 - 網上建指數有必要嗎?

網上建指數有必要嗎?

MySQL不同版本處理添加索引有三種方式:(1)復制表,這是InnoDB最早支持的創建索引的方式。顧名思義,創建索引是通過復制臨時表來實現的。用新的索引創建壹個新的臨時表,將原表的所有數據復制到臨時表中,然後重命名,完成創建索引的操作。該方法創建壹個索引,在創建過程中原始表是可讀的。但是會消耗兩倍的存儲空間。(2)原地模式這是原生MySQL 5::MySQL _ alter _ table();//判斷當前操作是否可以原地實現,不能原地改變的有://1::add _ index();...//創建索引數據字典row 0 merge::wait _ while _ table _ is _ used();//創建索引後,做最後的清理::MySQL _ alter _ table();//1::row _ log _ allocate();row _ log _ t * log =(row _ log _ t *)& amp;buf[2 * SRV _ sort _ buf _ size];//標識當前索引狀態為聯機創建,則//對該索引的DML操作將寫入行日誌,而不更新索引上的dict _ index _ set _ Online _ status(index,Online _ index _ creation);…//3::row _ merge _ build _ index();...//讀取、排序和插入新聚集索引的操作完成後//輸入Online和Inplace的真實區別。也是聯機操作的本質//-在Row 0 Log::Row _ merge _ read _ clustered _ index()函數中重用此過程中生成的行日誌,並在遍歷聚集索引後,將新索引的trx_id賦為聯機行日誌中最大的事務id。創建索引後,小於該事務ID的所有事務都不能使用新索引。通過聚集索引讀取數據時,讀取的是記錄的最新版本,那麽行日誌中也會存在這條記錄嗎?InnoDB如何處理這種情況?首先,答案是肯定的。當遍歷聚集索引以讀取記錄的最新版本時,這些記錄可能會被新事務修改/插入。在遍歷階段,這些記錄被應用到新的索引中。同時,這些記錄的操作也被記錄到了行日誌中,存在壹條記錄存在於新索引中,也存在於行日誌中的情況。當然,InnoDB也考慮到了這個問題。在重放行日誌的過程中,對於行日誌中的每條記錄,首先判斷它是否已經存在於新索引中(Row 0 Log . c::Row _ Log _ apply _ op _ low())。如果是,可以跳過當前行日誌(或者可以轉換操作類型)。例如,插入操作記錄在行日誌中。如果新索引中已經存在插入記錄,可以直接丟棄行日誌中的記錄(如果已有項與插入項完全相同);或者將INSERT轉換為UPDATE操作(行日誌記錄與新索引中的記錄不同,部分索引列也不同);在線添加索引是否存在Bug?答案也是肯定的,有bug。有壹個Bug,重現方案如下:create tablet 1 (a int主鍵,b int,c char(250))engine = innodb;插入t1(b,c)值(1,' aaaaaaaa ');//保證數據量足夠插入T1 (b,C)從T1中選擇B,C;插入t1(b,c)從t1中選擇b,c;插入t1(b,c)從t1中選擇b,c;… // max(a) = 196591從t1中選擇max(a);// b也沒有相同的項更新t 1 set b = a;會話1會話2 alter table t1添加唯壹索引idx _ t 1 _ b(b);插入t1(b,c)值(196592,' b ');//本次更新會生成b=196589的重復項,更新T1set B = 196589其中A = 196582;從t1中刪除其中a = 262127;在上面的測試中,首先為表準備足夠的數據,目的是session 1可以做聯機添加索引的讀取階段,session 2的新記錄也可以讀取。session 1在線添加索引完成(成功)後,執行以下兩條命令,結果如下:mysql & gt顯示創建表t 1;+——————————Table Create Table+———————————t 1創建Table ` t 1 `( ` a ` int(11)NOT NULL AUTO _ INCREMENT,` b` int(11)默認NULL,` c` char(250)默認NULLselect * from t1其中a在(196582,196589);+——————+這個Bug是由於處理行日誌的重放過程,沒有詳細考慮所有情況造成的。所以在MySQL版穩定之前,慎用!在線添加索引可以借鑒MySQL 5.6.7中的兩個文件操作函數:壹個是posix_fadvise()函數,指定POSIX_FADV_DONTNEED參數,實現無緩存讀寫:通過在Linux中保留緩沖區緩存狀態無緩沖I/O來提高Linux性能;其次,allocate()的函數,指定了FALLOC_FL_PUNCH_HOLE參數,可以在閱讀:Linux程序員手冊allocate (2)有類似需求的朋友可以嘗試壹下。Posix_fadvise函數+POSIX_FADV_DONTNEED參數,主要作用是丟棄緩存中幹凈的文件塊。因此,如果用戶不希望某個文件占用過多的文件系統緩存,可以定期調用fdatasync(),然後按照POSIX _ fadv _ Dontneed(POSIX _ fadv _ Dontneed)清除緩存中文件的幹凈塊。功能不錯!