我有一个用 Java 使用简单 SQL 编写的应用程序,因此这里没有自定义 MySQL 或 SQL Server - 它可能必须在其中任何一个上运行。一项数据持久操作必须从数据库中获取数据,将其与已提交的数据进行比较,然后相应地插入、更新或删除。
通过批处理 JDBC 调用,我显着提高了操作的性能。
所以我的 INSERT - 我只需调用 Statement.addBatch()
方法来插入整个数据集,然后 JDBC 驱动程序就会创建
INSERT INTO data (parentId, seriesDate, valueDate, value)
VALUES (a,b,c,d),(a,b,e,f),(a,b,g,h)... etc
删除 - 我只是用
删除整个批处理DELETE FROM data WHERE parentId = a AND seriesDate = b;
我可以重新插入它们。 (最好采取另一种方法,编写一个大长的
DELETE FROM data WHERE (parentId = 1 AND seriesDate = b)
OR (parentId = 2 AND seriesDate = c)
OR (parentId = 3 AND seriesDate = d) ...
但这不是这里的问题,我的主要问题是更新真的很慢 - 比插入慢两倍
我收到 1000 条单独的陈述:
UPDATE data SET value = 4
WHERE parentId = 1 AND seriesDate = '' AND valueDate = '';
在 SQL Server 中,更新与插入一样快,但在 MySQL 中,我发现它的运行速度慢了 10 倍。
我希望我忘记了一些相互兼容的方法,或者错过了一些我需要调整的 JDBC 连接配置,也许与我在每批中放入的项目数量结合起来。
[更新 2018-05-17] 这是请求的 DDL - 不幸的是我还无法更改它,因此任何涉及架构更改的建议都无济于事,至少不是这样年:(
CREATE TABLE data (
parentId INT UNSIGNED NOT NULL,
seriesDate DATE NOT NULL,
valueDate DATE NOT NULL,
value FLOAT NOT NULL,
versionstamp INT UNSIGNED NOT NULL DEFAULT 1,
createdDate DATETIME DEFAULT CURRENT_TIMESTAMP,
last_modified DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
CONSTRAINT pk_data PRIMARY KEY (parentId, seriesDate, valueDate),
CONSTRAINT fk_data_forecastid FOREIGN KEY (parentId)
REFERENCES forecast (id)
) MAX_ROWS 222111000;
CREATE TRIGGER trg_data_update BEFORE UPDATE ON data
FOR EACH ROW SET NEW.versionstamp = OLD.versionstamp + 1;
CREATE INDEX ix_data_seriesdate ON `data` (seriesDate);
插入:
INSERT INTO `data` (`parentId`, `valueDate`, `value`, `seriesDate`)
VALUES (52031,'2010-04-20',1.12344,'2013-01-10')
EXPLAIN PLAN:
id: 1
select_type: INSERT
table: data
partitions:
type: ALL
possible_keys: PRIMARY,ix_data_seriesdate
和更新:
UPDATE `data` SET `value` = -2367.0
WHERE `parentId` = 52005 AND `seriesDate` = '2018-04-20' AND `valueDate` = '2000-02-11'
EXPLAIN PLAN:
id: 1
select_type: UPDATE
table: data
partitions:
type: range
possible_keys: PRIMARY,ix_data_seriesdate
key: PRIMARY
key_len: 10
ref: const,const,const
rows: 1
filtered: 100
Extra: Using where
和删除:
DELETE FROM `data` WHERE `parentId` = 52030 AND `seriesDate` = '2018-04-20'
EXPLAIN PLAN:
id: 1
select_type: DELETE
table: data
partitions:
type: range
possible_keys: PRIMARY,ix_data_seriesdate
key: PRIMARY
key_len: 7
ref: const,const
rows: 1
filtered: 100
Extra: Using where
FYI 2 字段会自动更新 - last_modified
由 ON UPDATE
子句和 versionstamp
由触发器自动更新(同样,我不能放弃该功能)。
最佳答案
我发现改进 UPDATE 语句的方法:
- 使用辅助表(可以“批量”更新)
- 检查不必要的触发器
- 改进索引(针对 WHERE 子句)
- OLAP 或 OLTP 中间人临时表(它们允许批量更新)
EG
CREATE TABLE #TempData (
parentId INT UNSIGNED NOT NULL,
seriesDate DATE NOT NULL,
valueDate DATE NOT NULL,
value FLOAT NOT NULL
);
INSERT INTO #TempData ( parentId, seriesDate, valueDate, value ) VALUES ( .... ), ( .... ), ( .... );
UPDATE
data
SET
value = #TempData.value
FROM
#TempData
WHERE
data.parentId = #TempData.parentId AND
data.seriesDate = #TempData.seriesDate AND
data.valueDate = #TempData.valueDate;
关于mysql - 与 SQL Server 相比,如何提高 mySQL 中大量更新的速度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50380671/