【发布时间】:2019-12-27 08:00:18
【问题描述】:
我正在使用服务器版本:5.5.28-log MySQL Community Server (GPL)。
我有一个包含 279703655 条记录的大表,称为表 A。我必须在此表上执行与我的更改日志表 B 之一的连接,然后在新的 tmp 表 C 中插入匹配的记录。
B 表在列类型上有索引。
一个表由 prod_id、his_id 和其他列组成。一个表在 prod_id、history_id 列上都有索引。
当我要执行以下查询时
INSERT INTO C(prod,his_id,comm)
SELECT DISTINCT a.product_id,a.history_id,comm
FROM B as b INNER JOIN A as a ON a.his_id = b.his_id AND b.type="applications"
GROUP BY prod_id
ON DUPLICATE KEY UPDATE
`his_id` = VALUES(`his_id`);
插入记录需要 7 到 8 分钟。
即使我从表 A 执行简单的计数,也需要 15 分钟才能给我计数。
我也尝试过在 Limit 中插入记录的过程,但由于计数查询需要 15 分钟,它比以前慢了。
BEGIN
DECLARE n INT DEFAULT 0;
DECLARE i INT DEFAULT 0;
SELECT COUNT(*) FROM A INTO n;
SET i=5000000;
WHILE i<n DO
INSERT INTO C(product_id,history_id,comments)
SELECT a.product_id,a.history_id,a.comments FROM B as b
INNER JOIN (SELECT * FROM A LIMIT i,1) as a ON a.history_id=b.history_id;
SET i = i + 5000000;
END WHILE;
End
但上述代码也需要 15 到 20 分钟才能执行。
请建议我如何让它更快。
下面是EXPLAIN结果:
+----+-------------+-------+--------+---------------+---------+---------+-----------------+--------------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+---------+---------+-----------------+--------------+-------------+
| 1 | SIMPLE | a | ALL | (NULL) | (NULL) | (NULL) | (NULL) | 279703655 | |
| 1 | SIMPLE | b | eq_ref | PRIMARY | PRIMARY | 8 | DB.a.history_id | 1 | Using index |
+----+-------------+-------+--------+---------------+---------+---------+-----------------+--------------+-------------+
(来自评论)
CREATE TABLE B (
history_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
history_hash char(32) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
type enum('products','brands','partnames','mc_partnames','applications') NOT NULL,
stamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (history_id),
UNIQUE KEY history_hash (history_hash),
KEY type (type),
KEY stamp (stamp)
);
【问题讨论】:
-
GROUP BY prod_id在您选择的其他列中没有意义。您可能想要添加示例数据来演示您在此处尝试执行的操作。 -
请在您的查询中也发布
EXPLAIN结果,谢谢 -
我也在上面的查询中选择 product_id。这是上述查询的解释结果。 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE a ALL 279703655 1 SIMPLE b eq_ref PRIMARY PRIMARY 8 DB.a.history_id 1 使用索引
-
@Tim Biegeleisen 实际上我有更改日志表,其中我最近 7 天更改了添加/编辑/更新记录,在上述情况表 B 中。表 A 包含所有应用程序历史记录。我只需要获取最近 7 天更改过的应用记录。
-
最近 7 天更改了吗?然而,使用的 TIMESTAMP 或 DATETIME 没有标准?我希望至少一个变更日志表应该有这样的列。
标签: mysql sql optimization