通常來說,在MyISAM裡讀寫操作是串列的,但當對同一個表進行查詢和插入操作時,為了降低鎖競爭的頻率,根據concurrent_insert的設定,MyISAM是可以平行處理查詢和插入的:
當concurrent_insert=0時,不允許並發插入功能。
當concurrent_insert=1時,允許對沒有洞洞的表使用並發插入,新資料位元於資料檔案結尾(預設)。
當concurrent_insert=2時,不管表有沒有洞洞,都允許在資料檔案結尾並發插入。
這樣看來,把concurrent_insert設定為2是很划算的,至於由此產生的檔案片段,可以定期使用OPTIMIZE TABLE文法最佳化。
max_write_lock_count:
預設情況下,寫操作的優先順序要高於讀操作的優先順序,即便是先發送的讀請求,後發送的寫請求,此時也會優先處理寫請求,然後再處理讀請求。這就造成一 個問題:一旦我發出若干個寫請求,就會堵塞所有的讀請求,直到寫請求全都處理完,才有機會處理讀請求。此時可以考慮使用 max_write_lock_count:
max_write_lock_count=1
有了這樣的設定,當系統處理一個寫操作後,就會暫停寫操作,給讀操作執行的機會。
low-priority-updates:
我們還可以更乾脆點,直接降低寫操作的優先順序,給讀操作更高的優先順序。
low-priority-updates=1
綜合來看,concurrent_insert=2是絕對推薦的,至於max_write_lock_count=1和low-priority- updates=1,則視情況而定,如果可以降低寫操作的優先順序,則使用low-priority-updates=1,否則使用 max_write_lock_count=1。
set-variable = max_allowed_packet=1M
set-variable = net_buffer_length=2K
在myisam engine下
1. 盡量使用insert into table_name values (...), (.....),(.....)這樣形式插入資料,避免使用inset into table_name values (); inset into table_name values (); inset into table_name values ();
2 增加bulk_insert_buffer_size(預設8M)
3 如果是非空表,使用alter table table_name disable keys,然後load data infile,匯入完資料在執行:
alter table table_name enable keys. 如果是空表,就不需要這個操作,因為myisam表在空表中匯入資料時,是先匯入資料然後建立indexs。
4 在插入資料時考慮使用:insert delayed....這樣操作實際mysql把insert操作放到隊列裡面,進行相對集中的插入,速度更快。
5. 使用load data infile 比使用insert 操作快近20倍,盡量使用此操作。
在innodb engine下
1.匯入資料之前執行set unique_checks=0來禁止對唯一索引的檢查,資料匯入完成之後再運行set unique_checks=1.
2. 匯入資料之前執行set foreign_key_checks=0來禁止對外鍵的檢查,資料匯入完成之後再執行set foreign_key_checks=1.
3.匯入資料之前執行set autocommit=0禁止自動事務的自動認可,資料匯入完成之後,執行set autocommit=1 恢複自動認可操作。
使用innodb engine的表,實體儲存體都是按PK的順序存的。不能使用類似於myisam一樣disable keys.
硬體上提高磁碟的I/0對插入速度很有好處(所以如果進行大資料量的匯入匯出工作,盡量在比較NB的硬體上進行,能縮減完成的時間,已經防止出現問題)。
當一個線程對一個表執行一個DELAYED語句時,如果不存在這樣的處理常式,一個處理器線程被建立以處理對於該表的所有DELAYED語句。
線程檢查處理常式是否已經獲得了一個DELAYED鎖;如果沒有,它告訴處理常式去獲得。即使其他的線程有在表上的一個READ或WRITE鎖,也能獲得 DELAYED鎖。然而,處理常式將等待所有ALTER TABLE鎖或FLUSH TABLES以保證表結構是最新的。
線程執行INSERT語句,但不是將行寫入表,它把最後一行的副本放進被處理器線程管理的一個隊列。任何語法錯誤都能被線程發覺並報告給客戶程式。
顧客不能報告結果行的重複次數或AUTO_INCREMENT值;它不能從伺服器獲得它們,因為INSERT在插入操作完成前返回。如果你使用C API,同樣原因,mysql_info()函數不返回任何有意義的東西。
當行被插入到表中時,更新日誌有處理器線程更新。在多行插入的情況下,當第一行被插入時,更新日誌被更新。
在每寫入delayed_insert_limit行後,處理器檢查是否任何SELECT語句仍然是未完成,如果這樣,在繼續之前允許執行這些語句。
當處理器在它的隊列中沒有更多行時,表被解鎖。如果在delayed_insert_timeout秒內沒有收到新的INSERT DELAYED命令,處理器終止。
如果已經有多於delayed_queue_size行在一個特定的處理器隊列中未解決,線程等待直到隊列有空間。這有助於保證mysqld伺服器對延遲的記憶體隊列不使用所有記憶體。
處理器線程將在Command列的MySQL進程表中顯示delayed_insert。如果你執行一個FLUSH TABLES命令或以KILL thread_id殺死它,它將被殺死,然而,它在退出前首先將所有排隊的行存進表中。在這期間,這次它將不從其他線程接受任何新的INSERT命令。如 果你在它之後執行一個INSERT DELAYED,將建立一個新的處理器線程。
注意,上述意味著,如果有一個INSERT DELAYED處理器已經運行,INSERT DELAYED命令有比正常INSERT更高的優先順序!其他更新命令將必須等到INSERT DELAY排隊變空、殺死處理器線程(用KILL thread_id)或執行FLUSH TABLES。
下列狀態變數提供了關於INSERT DELAYED命令的資訊: Delayed_insert_threads 處理器線程數量
Delayed_writes 用INSERT DELAYED被寫入的行的數量
Not_flushed_delayed_rows 等待被寫入的行數字