我有MariaDb实例和临时表。工作流程:
insert into TEMP1 (xxx,yyy) values(?,?),(?,?),(?,?),(?,?)...
Worflow在一个线程中执行。 问题定义:首次运行此工作流程在1-3秒内插入40K记录,所有连续运行在30-40秒内插入40K。
任何人都可以告诉如何让它在所有运行中运行1-3秒吗?
表格定义:
CREATE TEMPORARY TABLE IF NOT EXISTS TEMP1 (
uuid varchar(80) COLLATE utf8_unicode_ci NOT NULL,
raw_content longtext COLLATE utf8_unicode_ci NOT NULL,
security_level varchar(255) COLLATE utf8_unicode_ci NOT NULL,
key_name varchar(255) COLLATE utf8_unicode_ci NOT NULL,
stage_user_uuid varchar(80) NOT NULL,
data_type varchar(255) COLLATE utf8_unicode_ci NOT NULL,
string_value varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
integer_value bigint(20) DEFAULT NULL,
double_value double DEFAULT NULL,
date_value datetime DEFAULT NULL,
INDEX user_uuid_idx (stage_user_uuid)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
答案 0 :(得分:1)
问题是我用jdbcTemplate.batchUpdate
以一种非常奇怪的方式工作。我设置了rewriteBatchedStatements=true
。
第一次运行真正执行过的声明
insert into TEMP1 (xxx,yyy) values(?,?),(?,?),(?,?),(?,?);
未知原因的下一个语句逐个执行语句
insert into TEMP1 (xxx,yyy) values(?,?);
insert into TEMP1 (xxx,yyy) values(?,?);
insert into TEMP1 (xxx,yyy) values(?,?);
这导致了缓慢。
在具有此后缀的日志中可以看到实际语句到连接字符串:&logger=com.mysql.jdbc.log.Slf4JLogger&profileSQL=true
我最终定期准备好批处理语句,并且完美无缺。
ps.addBatch()
ps.executeBatch()
ps.clearBatch()
问题的根源是jdbcTemplate.batchUpdate
使用JdbcUtils.supportsBatchUpdates
因某些原因失败。我使用org.apache.tomcat:tomcat-jdbc:8.0.30
pool
driver 'supportsBatchUpdates' method threw exception
java.sql.SQLException: PooledConnection has already been closed.
at org.apache.tomcat.jdbc.pool.DisposableConnectionFacade.invoke(DisposableConnectionFacade.java:87)
at com.sun.proxy.$Proxy37.getMetaData(Unknown Source)
at org.springframework.jdbc.support.JdbcUtils.supportsBatchUpdates(JdbcUtils.java:359)
at org.springframework.jdbc.core.JdbcTemplate$4.doInPreparedStatement(JdbcTemplate.java:897)
at org.springframework.jdbc.core.JdbcTemplate$4.doInPreparedStatement(JdbcTemplate.java:890)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:589)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:617)
at org.springframework.jdbc.core.JdbcTemplate.batchUpdate(JdbcTemplate.java:890)
答案 1 :(得分:-1)
表上的索引数是插入性能的最主要因素。表具有的索引越多,执行就越慢。 insert语句是唯一不能直接从索引中获益的操作,因为它没有where子句。
如果表上有索引,则数据库必须确保通过这些索引找到新条目。因此,它必须将新条目添加到该表的每个索引。因此,索引的数量是insert语句的成本的乘数。
为了优化插入性能,保持索引数量很小非常重要。
了解更多here。