Muốn đo index làm chậm tốc độ ghi (INSERT/UPDATE) bao nhiêu lần, bạn phải so sánh:
Sau đó lấy tỷ lệ.
Vì MySQL không có sẵn metric “index làm chậm bao nhiêu lần”, ta phải benchmark thủ công bằng stored procedure.
DELIMITER $$
CREATE PROCEDURE benchmark_index_write()
BEGIN
DECLARE i INT DEFAULT 0;
DECLARE start_time DATETIME(6);
DECLARE end_time DATETIME(6);
DECLARE no_index_time DOUBLE;
DECLARE with_index_time DOUBLE;
-- Xoá bảng nếu tồn tại
DROP TABLE IF EXISTS test_index_perf;
-- Tạo bảng không index
CREATE TABLE test_index_perf (
id INT AUTO_INCREMENT PRIMARY KEY,
col1 VARCHAR(255),
col2 INT
) ENGINE=InnoDB;
-- =========================
-- TEST KHÔNG INDEX
-- =========================
SET start_time = NOW(6);
SET i = 0;
WHILE i < 100000 DO
INSERT INTO test_index_perf (col1, col2)
VALUES (UUID(), FLOOR(RAND()*100000));
SET i = i + 1;
END WHILE;
SET end_time = NOW(6);
SET no_index_time = TIMESTAMPDIFF(MICROSECOND, start_time, end_time) / 1000000;
-- =========================
-- ADD INDEX
-- =========================
CREATE INDEX idx_col2 ON test_index_perf(col2);
-- =========================
-- TEST CÓ INDEX
-- =========================
SET start_time = NOW(6);
SET i = 0;
WHILE i < 100000 DO
INSERT INTO test_index_perf (col1, col2)
VALUES (UUID(), FLOOR(RAND()*100000));
SET i = i + 1;
END WHILE;
SET end_time = NOW(6);
SET with_index_time = TIMESTAMPDIFF(MICROSECOND, start_time, end_time) / 1000000;
-- =========================
-- KẾT QUẢ
-- =========================
SELECT
no_index_time AS seconds_without_index,
with_index_time AS seconds_with_index,
(with_index_time / no_index_time) AS slowdown_ratio;
END$$
DELIMITER ;
Chạy:
CALL benchmark_index_write();
| seconds_without_index | seconds_with_index | slowdown_ratio |
|---|---|---|
| 1.2 | 2.8 | 2.33 |
=> Nghĩa là index làm chậm ghi khoảng 2.3 lần
Phụ thuộc:
Thực tế:
| Số index phụ | Ghi chậm thêm |
|---|---|
| 1 index | ~1.5–2x |
| 3–4 index | ~3–5x |
| 8+ index | Có thể 10x |
Thay vì procedure loop 100k lần (vì slow do context switch):
Dùng:
INSERT INTO table SELECT ...
Hoặc generate số bằng recursive CTE (MySQL 8).
Hoặc đo bằng:
SHOW GLOBAL STATUS LIKE 'Innodb_rows_inserted'; SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_write_requests';
Hoặc dùng:
performance_schema.events_statements_summary_by_digest