1. 测试 replace into 引发死锁
2. 测试 replace 和INSET INTO *** ON DUPLICATE KEY UPDATE *** 性能差
1、 数据库系统:
名称:Mysql 5.5.31
引擎:innodb
字符集:UTF8
安装方式:源码编译安装
2、 数据库部署环境:
软硬件环境:Linux(CentOS-6.2-x86_64)
Mysql 自带 Mysqlslap
所有操作前重启mysql,避免缓存。
测试表:
CREATE TABLE`test_replace_into` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`wechat_init_code` int(11) NOT NULL,
`used` varchar(50) DEFAULT '0',
`expire` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `ii` (`wechat_init_code`)
) ENGINE=InnoDBDEFAULT CHARSET=utf8;
insert_on_duplicate.sql:
SET@mm=ROUND(RAND()*100000);
SET@nn=ROUND(RAND()*100000);
INSERT INTOtest.`test_replace_into`(wechat_init_code,used,expire) VALUES (@mm,@nn,@nn) ONDUPLICATE KEY UPDATE used =@nn,expire=@nn ;
replace_into.sql:
SET@mm=ROUND(RAND()*100000);
SET @nn=ROUND(RAND()*100000);
REPLACE INTOtest.`test_replace_into` (`wechat_init_code`,`used`,`expire`) VALUES(@mm,@nn,@nn);
insert_on_duplicate_with_select.sql:
SET@mm=ROUND(RAND()*100000);
SET@nn=ROUND(RAND()*100000);
INSERT INTOtest.`test_replace_into`(wechat_init_code,used,expire) VALUES (@mm,@nn,@nn) ONDUPLICATE KEY UPDATE used =@nn,expire=@nn ;
CALLtest.`proc_test_replace_int`();
replace_into_with_select.sql:
SET@mm=ROUND(RAND()*100000);
SET@nn=ROUND(RAND()*100000);
REPLACE INTOtest.`test_replace_into` (`wechat_init_code`,`used`,`expire`) VALUES(@mm,@nn,@nn);
CALLtest.`proc_test_replace_int`();
test.`proc_test_replace_int`():
DELIMITER $$
USE `test`$$
DROP PROCEDURE IFEXISTS `proc_test_replace_int`$$
CREATEDEFINER=`root`@`%` PROCEDURE `proc_test_replace_int`()
BEGIN
SET @mm=ROUND(RAND()*100000);
PREPARE sql2 FROM 'SELECT * FROMtest.`test_replace_into` LIMIT ?,10 ;';
EXECUTE sql2 USING @mm;
END$$
DELIMITER ;
前置操作A:建表:
前置操作B:使用文件(2.test_data.sql)填充数据。
测试语句:
servicemysql restart
mysqlslap -uroot -proot --delimiter=";" --concurrency=1000 --number-of-queries=10000 --iterations=10--query="insert_on_duplicate.sql"
结果:
servicemysql restart
mysqlslap -uroot -proot --delimiter=";" --concurrency=1000 --number-of-queries=10000 --iterations=10--query="replace_into.sql"
结果:
前置操作A:删除表中的自增ID,进行测试
测试语句:
servicemysql restart
mysqlslap -uroot -proot --delimiter=";" --concurrency=1000 --number-of-queries=10000 --iterations=10--query="insert_on_duplicate.sql"
servicemysql restart
mysqlslap -uroot -proot --delimiter=";" --concurrency=1000 --number-of-queries=10000 --iterations=10--query="replace_into.sql"
mysql-uroot -proot -e 'TRUNCATE TABLE test.`test_replace_into`;'
mysqlslap -uroot -proot --delimiter=";" --concurrency=1000 --number-of-queries=10000 --iterations=10--query="replace_into.sql"
mysql -uroot-proot -e 'TRUNCATE TABLE test.`test_replace_into`;'
mysqlslap -uroot -proot --delimiter=";" --concurrency=1000 --number-of-queries=10000 --iterations=10--query="insert_on_duplicate.sql"
结论: replace into容易死锁
mysql-uroot -proot -e 'TRUNCATE TABLE test.`test_replace_into`;'
mysqlslap -uroot -proot --delimiter=";" --concurrency=1000 --number-of-queries=10000 --iterations=10--query="replace_into.sql"
mysql-uroot -proot -e 'TRUNCATE TABLE test.`test_replace_into`;'
mysqlslap -uroot -proot --delimiter=";" --concurrency=1000 --number-of-queries=10000 --iterations=10--query="insert_on_duplicate.sql"
结论: 接近
service mysql restart
mysqlslap -uroot -proot --delimiter=";" --concurrency=1000 --number-of-queries=10000 --iterations=5--query="replace_into_with_select.sql"
service mysql restart
mysqlslap -uroot -proot --delimiter=";" --concurrency=1000 --number-of-queries=10000 --iterations=5--query="insert_on_duplicate_with_select.sql"
带自增ID,使用replace 容易死锁,不要使用replace into,效率接近。
当数据量达到100W基本是,单纯修改,少量慢日志,同时的改查,慢日志明显。两者性能接近。
慢日志频繁时应该考虑降低写入并发。