我有两个表:Articles
存储有关文章的信息,PageLinks
存储页面之间的超链接。架构如下。
CREATE TABLE `Articles` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`slug` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`label` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `slug_UNIQUE` (`slug`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
CREATE TABLE `PageLinks` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`from_id` int(11) NOT NULL,
`to_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `index4` (`to_id`,`from_id`),
KEY `fk_PageLinks_1` (`from_id`),
KEY `fk_PageLinks_2` (`to_id`),
CONSTRAINT `fk_PageLinks_1` FOREIGN KEY (`from_id`) REFERENCES `Articles` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_PageLinks_2` FOREIGN KEY (`to_id`) REFERENCES `Articles` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
我有几百万个 slug 对,它们指示相应页面之间的超链接。我正在尝试从这些 slug 对加载 PageLinks 表。
目前,我有一个 python 程序为每个 slug 发出 select id
查询,以将 slug 对转换为文章 id 对。然后将 ID 对写入文件并使用 load data infile
加载。此外,如果 Articles 表中不存在 slug,程序会插入一个没有标签的虚拟行,然后使用该行的 ID。
我正在尝试优化程序以更快地加载条目(我有大约 18GB 的 slug 对要加载)。我相信如果可以批量执行 slug->id 解析和页面链接插入(从而避免每个 SELECT 开销),则可以实现一些加速。在 mysql 中执行此操作的最佳方法是什么?
最佳答案
为每个 slug 单独制作一个 SELECT
确实效率低下。
你应该将你的 slug 对加载到一个表中:
CREATE TABLE pairs
(
slug1 VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
slug2 VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL
);
,用你的对加载它,然后发出以下语句:
INSERT IGNORE
INTO Articles (slug)
SELECT slug1
FROM pairs;
INSERT IGNORE
INTO Articles (slug)
SELECT slug2
FROM pairs;
INSERT
INTO pairs (from_id, to_id)
SELECT a1.id, a2.id
FROM pairs
JOIN articles a1
ON a1.slug = slug1
JOIN articles a2
ON a2.slug = slug2;
关于mysql查询选择键并插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5421926/