Mysql
MySQL:為什麼使用事務插入數據比沒有事務更快
我正在使用儲存過程生成由給定範圍內的前綴和數字組成的序列(等序列“AB100”、“AB101”、…、“AB199”、“AB200”)
儲存過程包括
REPEAT
循環,在循環中構造字元串並插入到表中。當所有循環都在事務內部時,程序執行得非常快,但是當我在沒有事務的情況下插入數據時,執行程序的時間要長 400 倍。
誰能解釋一下,為什麼會這樣?
或者,如果有人對如何生成這樣的序列有更好的了解,我會很高興聽到他們的聲音。
這是程式碼:
-- create table CREATE TABLE seq ( Code CHAR(12) ) ENGINE = INNODB; -- fast procedure with transactions DELIMITER $$ CREATE PROCEDURE sp_sequence(IN val_prefix CHAR(2), IN val_from INT, IN val_to INT ) BEGIN START TRANSACTION; SET @val = val_from; REPEAT INSERT INTO seq (Code) VALUES (CONCAT(val_prefix, @val)); SET @val = @val + 1; UNTIL @val > val_to END REPEAT; COMMIT; END$$ DELIMITER ; -- slow procedure without transactions DROP PROCEDURE IF EXISTS sp_sequence_slow; DELIMITER $$ CREATE PROCEDURE sp_sequence_slow(IN val_prefix CHAR(2), IN val_from INT, IN val_to INT ) BEGIN SET @val = val_from; REPEAT INSERT INTO seq (Code) VALUES (CONCAT(val_prefix, @val)); SET @val = @val + 1; UNTIL @val > val_to END REPEAT; END$$ DELIMITER ;
以下是結果:
mysql> CALL sp_sequence('TX', 11000, 12000); Query OK, 0 rows affected (0.09 sec) mysql> CALL sp_sequence_slow('TX', 11000, 12000); Query OK, 0 rows affected (40.07 sec)
如果沒有顯式事務,所有語句都處於自動送出模式 - 因此每個插入都是單獨的事務。這會帶來一些同步等成本。
如果您插入所有行而不在其間送出,mysql 可以在記憶體/記憶體中執行大量操作,並且只將其同步到磁碟一次(簡化,記憶體可能會被文件系統和作業系統多次刷新)。
在沒有顯式事務的情況下,每個插入必須等待磁碟確認寫入所有更改,然後返回並讓循環繼續。有時可以通過在每次事務之後定期刷新來稍微放鬆一下,但是您可能會在失敗 IIRC 時失去一些數據。
另一方面 - 如果您在一個事務中插入/更新太多行,則包含可能回滾的資訊的日誌可能會增長很多並減慢一切。所以事務大小應該是合理的(不是數百萬行)。
一些提示:http ://dev.mysql.com/doc/refman/5.5/en/optimizing-innodb-transaction-management.html