优化master-detail插入语句

时间:2010-05-06 15:43:15

标签: mysql query-optimization bulkinsert

任务

经过一天的运行(相对于近1 GB的数据),一组语句每秒下降到40次插入。我希望将其增加一个数量级或两个数量级。

SQL代码

插入信息的代码分为两部分:主记录和详细记录。主记录:

INSERT INTO MONTH_REF (DISTRICT_ID, STATION_ID, CATEGORY_ID, YEAR, MONTH) VALUES
('101', '0066', '010', 1984, 07);

详细记录:

INSERT INTO DAILY (MONTH_REF_ID, AMOUNT, DAILY_FLAG_ID, DAY) VALUES ((SELECT ID
FROM MONTH_REF M WHERE M.DISTRICT_ID = '101' AND M.STATION_ID = '0066' AND M.CAT
EGORY_ID = '010' AND M.YEAR = 1984 AND M.MONTH = 07), 0, ' ', 1);

INSERT INTO DAILY (MONTH_REF_ID, AMOUNT, DAILY_FLAG_ID, DAY) VALUES ((SELECT ID
FROM MONTH_REF M WHERE M.DISTRICT_ID = '101' AND M.STATION_ID = '0066' AND M.CAT
EGORY_ID = '010' AND M.YEAR = 1984 AND M.MONTH = 07), 0.5, ' ', 2);

INSERT INTO DAILY (MONTH_REF_ID, AMOUNT, DAILY_FLAG_ID, DAY) VALUES ((SELECT ID
FROM MONTH_REF M WHERE M.DISTRICT_ID = '101' AND M.STATION_ID = '0066' AND M.CAT
EGORY_ID = '010' AND M.YEAR = 1984 AND M.MONTH = 07), 0, 'T', 3);

提议的解决方案

建议的解决方案通过将每个MONTH_REF_ID存储在局部变量中来消除查找,如下所示:

INSERT INTO MONTH_REF (DISTRICT_ID, STATION_ID, CATEGORY_ID, YEAR, MONTH) VALUES
('101', '0066', '010', 1984, 07);

SET @month_ref_id := (SELECT LAST_INSERT_ID());

详细说明随后变为:

INSERT INTO DAILY (MONTH_REF_ID, AMOUNT, DAILY_FLAG_ID, DAY) VALUES (@month_ref_id, 0, ' ', 1);
INSERT INTO DAILY (MONTH_REF_ID, AMOUNT, DAILY_FLAG_ID, DAY) VALUES (@month_ref_id, 0.5, ' ', 2);
INSERT INTO DAILY (MONTH_REF_ID, AMOUNT, DAILY_FLAG_ID, DAY) VALUES (@month_ref_id, 0, 'T', 3);

约束

MONTH_REF表有一个AUTO_INCREMENT主键,并在其上编入索引。 DAILY表没有索引,也没有主键。主键可以添加到DAILY表中,如果有帮助的话。

问题

执行(十亿左右)插入语句比提出的解决方案更有效的方法是什么?

谢谢!

1 个答案:

答案 0 :(得分:1)

此解决方案有效:

INSERT INTO MONTH_REF (DISTRICT_ID,STATION_ID,CATEGORY_ID,YEAR,MONTH) VALUES('101','QFEG','012',1973,08);
SET @month_ref_id := (SELECT LAST_INSERT_ID());
INSERT INTO DAILY (MONTH_REF_ID,AMOUNT,DAILY_FLAG_ID,DAY) VALUES(@month_ref_id,0,' ',1),(@month_ref_id,0,' ',2),(@month_ref_id,0,' ',3);

插入量上升了大约四个数量级。