當乙個執行緒對乙個表執行乙個delayed語句時,如果不存在這樣的處理程式,乙個處理器執行緒被建立以處理對於該錶的所有delayed語句。
通常來說,在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 等待被寫入的行數字
mysql效能優化 插入資料的優化(筆記三)
插入資料時,影響插入速度的主要是索引 唯一性校驗 一次插入的資料條數等。插入資料的優化,不同的儲存引擎優化手段不一樣,在mysql中常用的儲存引擎有,myisam和innodb,兩者的區別 對於非空表,插入記錄時,mysql會根據表的索引對插入的記錄建立索引。如果插入大量資料,建立索引會降低插入資料...
mysql插入大量資料,時間的優化。
背景 業務場景假設,公司原有excel記錄了千萬級客戶的相關資料,公司業務結構實現了資訊化的布局,需要在新開發的crm系統中匯入千萬級的客戶資料。此時需要用到mysql的insert操作來插入使用者的海量資料。普通情況下,會使用for迴圈一條一條的插入資料。假設客戶的資料量為10萬條資料。conne...
MySQL優化之海量資料批量插入
問 為何對同乙個表的插入多執行緒會比單執行緒快?同一時間對乙個表的寫操作不應該是獨佔的嗎?答 在資料裡做插入操作的時候,整體時間的分配是這樣的 鏈結耗時 30 傳送query到伺服器 20 解析query 20 插入操作 10 詞條數目 插入index 10 index的數目 關閉鏈結 10 從這裡...