use*_*050 9 mysql database optimization performance insert
我想写一个程序向表中添加新项.这个项目有一个唯一的密钥name,它可以由100个线程中的一个创建,所以我需要确保它只插入一次.
我有两个想法:
使用 insert ignore
如果没有返回的行,则从数据库中获取它select然后insert再到表.
哪个选项更好?有更优越的想法吗?
SELECT + INSERT - 两次往返服务器,因此速度较慢.
INSERT IGNORE - 需要PRIMARY或UNIQUE键来决定是否抛出新的INSERT.如果这适合你,那可能是最好的.
REPLACE - 是DELETE + INSERT.这很少是最好的.
INSERT ... ON DUPLICATE KEY UPDATE - 这使您可以INSERT(如果未找到PRIMARY/UNIQUE键)或 UPDATE.如果您需要在现有行中更新所需的内容,则可以使用此选项.
晚会晚了,但我正在考虑类似的事情。
我创建了下表来每天跟踪许可证上的活动用户:
CREATE TABLE `license_active_users` (
`license_active_user_id` int(11) NOT NULL AUTO_INCREMENT,
`license_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`date` date NOT NULL,
PRIMARY KEY (`license_active_user_id`),
UNIQUE KEY `license_id` (`license_id`,`user_id`,`date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Run Code Online (Sandbox Code Playgroud)
换句话说,其余3列中有1个主键和1个唯一索引。
然后,我将100万个唯一的行插入到表中。
尝试重新插入相同数据的子集(10,000行)会产生以下结果:
INSERT IGNORE:38秒INSERT ... ON DUPLICATE KEY UPDATE:40秒if (!rowExists("SELECT ...")) INSERT:<2秒如果表中还没有这些10,000行:
INSERT IGNORE:34秒INSERT ... ON DUPLICATE KEY UPDATE:41秒if (!rowExists("SELECT ...")) INSERT:21秒因此,结论必须if (!rowExists("SELECT ...")) INSERT是迄今为止最快的-至少对于此特定表配置而言。
缺少的测试是if (rowExists("SELECT ...")){ UPDATE } else { INSERT },但我认为INSERT ... ON DUPLICATE KEY UPDATE此操作更快。
但是,对于您的特殊情况,我会选择使用它,INSERT IGNORE因为(据我所知)这是一个原子操作,在使用线程时可以为您节省很多麻烦。