Mysql

MySQL:為什麼使用事務插入數據比沒有事務更快

  • May 27, 2015

我正在使用儲存過程生成由給定範圍內的前綴和數字組成的序列(等序列“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

引用自:https://dba.stackexchange.com/questions/102533