【发布时间】:2021-06-08 07:41:42
【问题描述】:
我有一个 100GB 的大型网站内容数据集,其中包含大约 10 亿行,我已将它们编入单个 MySQL 8 表中。
CREATE TABLE `inner_pages_content` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`page_id` INT(10) UNSIGNED NULL DEFAULT NULL,
`page_word` VARCHAR(50) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
`word_source` TINYINT(3) UNSIGNED NULL DEFAULT NULL,
`word_frequency` TINYINT(3) UNSIGNED NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `FK_inner_pages_content_inner_pages` (`page_id`) USING BTREE,
INDEX `page_word` (`page_word`) USING BTREE,
CONSTRAINT `FK_inner_pages_content_inner_pages` FOREIGN KEY (`page_id`) REFERENCES `rocket_test`.`inner_pages` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1629374935
然后,我对其运行与此类似的查询,以针对特定关键字建立特定页面的相关性分数。
SELECT page_id, word_source, word_frequency FROM inner_pages_content WHERE page_word IN
('docker', 'software development', 'linux', 'microsoft', 'computer software');
除了速度慢得令人痛苦之外,一切都运行良好。我发现的一种解决方案是将所有内容都移到 GCP 的 BigQuery 中,但在我永久地追求这条路线并注销 CloudSQL/MySQL 之前,我想看看是否有什么办法可以让我的解决方案继续使用 CloudSQL/MySQL。
在我的 SSD 本地和具有 500GB SSD 的 CloudSQL 上,这些查询都需要 120-200 秒才能完成。
我相信一个问题(很有可能我错了!)是由于 100GB 内存的成本,我没有将整个表放在本地内存或 CloudSQL 中,因此它总是从磁盘中提取结果。
有趣的是,当我 COUNT(*) 匹配结果而不是 SELECT 时,它非常快。通常不到 0.5 秒。
我可以做些什么来加快这个查询?
其他信息
【问题讨论】:
-
一个 IN 语句几乎与几个 OR 语句相同,而且通常很慢。通常为每个案例创建一个语句然后使用 UNION ALL 会更快
-
我会考虑另外将
page_word VARCHAR(50)转换为 ENUM。
标签: mysql sql google-cloud-sql