mysql - 通过数百万条记录表连接优化 MySQl 查询性能
问题描述
我必须使用两个表连接将数据插入到一个临时表中。作为我的一个具有hist_data_app(大约 3 亿条)记录的表之一完全执行需要 30 分钟。我想知道我如何更优化查询以使其快点。
第一个表包含带有一些特定数据的更改日志数据,而其他表包含与之相关的所有数据。下面是我的两个表创建语句。
CREATE TABLE `hist_data_app` (
`product_id` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
`application_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`year_id` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
`history_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0',
`field_name` VARCHAR(60) NOT NULL COLLATE 'utf8_unicode_ci',
`old_value` TEXT NOT NULL COLLATE 'utf8_unicode_ci',
`new_value` TEXT NOT NULL COLLATE 'utf8_unicode_ci',
`comments` TEXT NOT NULL,
INDEX `ps` (`product_id`, `history_id`)
)
CREATE TABLE `histry_log` (
`history_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0',
`history_hash` CHAR(32) NOT NULL COLLATE 'utf8_unicode_ci',
`type` ENUM('products','brands','partnames','mc_partnames','applications') NOT NULL,
`user_id` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0',
`stamp` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
`source` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0',
`source_data` TEXT NOT NULL COLLATE 'utf8_unicode_ci',
`description` TEXT NOT NULL COLLATE 'utf8_unicode_ci',
PRIMARY KEY (`history_id`),
INDEX `Types` (`type`)
)
这是我的解释结果
EXPLAIN
SELECT DISTINCT a.product_id
, a.history_id
, a.comments
, a.field_name
FROM history_log b
JOIN hist_data_app a
ON a.history_id = b.history_id
GROUP
BY product_id;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE a ALL NULL NULL NULL NULL 278327646 Using temporary; Using filesort
1 SIMPLE b eq_ref PRIMARY PRIMARY 8 LONGBOW_data.a.history_id 1 Using index
history_app_data 表
product_id application_id year_id history_id
598865023 12813220945 92 16777304
598865023 12813220945 93 16777304
598865023 12813221222 93 16777304
598865023 12815428123 94 16777304
598865023 12813221833 92 16777304
598865023 12813221833 93 16777304
598865023 12815457549 92 16777304
598865023 12815457549 93 16777304
598865023 12815457549 94 16777304
解决方案
- 查询格式不正确;在你解决这个问题之前,我们不应该讨论它。阅读“only_full_group_by”。
- 可能永远不会“正确”同时拥有
GROUP BY
和。DISTINCT
SELECT
- 你有“爆炸-内爆”综合症。这是当您执行 a 时
JOIN
,它会构建一个大型临时表,然后是 aGROUP BY
以缩小到您可能必须在其中一个表中开始的内容。 - 结果集仍然很大;你打算如何处理结果?
- 你真的应该
PRIMARY KEY
在每张桌子上都有一个。如果这是唯一的(history_id, product_id)
,请将其作为 PK。(请注意,我交换了顺序,如其他评论中所述。) year_id
- 那是 a 的归一化YEAR
吗?不值得。只需将年份放在表中即可;没有额外的查找。- 另一张桌子有多大?(我可能在咆哮错误的优化。)
这可能会为您提供相同的数据,但速度要快得多:
SELECT a.product_id , a.history_id , a.comments , a.field_name FROM ( SELECT DISTINCT history_id FROM history_log ) AS b JOIN hist_data_app a ON a.history_id = b.history_id GROUP BY product_id;
您将不得不对表格进行一些结构更改;计划一些停机时间。
如果您只需要有关 Hammers 的数据,请向我们展示会WHERE
限制输出的子句。针对该查询进行优化可能与您的问题中的 30 分钟查询有很大不同!
修复我和其他人建议的大部分内容,然后用新的架构等返回一个新问题。(这个问答太混乱了,无法继续。)
推荐阅读
- c++ - 使用混合加速在第二个位图中绘制位图放大
- postgresql - 如何在视图上使用 TRIM
- oracle - 按计数选择乘法 SQL、Group By、Oracle
- php - 使用 codeigniter 和 mysql 插入数据失败
- c++ -
- python - 在 apache 上部署 django 时没有发现模块错误
- python - 获取最终预测掩码中的轮廓坐标
- qt - QFontMetrics 缺少baseline() 方法
- sql - 从 SQL Server 2008 中的数据数自动增加列
- python - 如何使用 pylucene 创建 CustomSimilarity 类?