我必须使用两个表连接在一个临时表中插入数据。作为一个有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
基于你对我的评论的反应,你应该与你现在已经设置的好。 因为您主要考虑的是单个产品,所以您的Hist_Data_App表在第一个位置有product_id的索引,这也是您所希望的,但同时也有history_id来连接到日志表将会有所帮助。 只需添加您的where子句并测试某些产品。
SELECT
hd.product_id,
hd.history_id,
hd.comments,
hd.field_name
FROM
hist_data_app hd
where
-- or whatever single product ID you want
hd.product_id = 12345
现在,我不知道您是否真的需要distinct,但可以添加回来没有问题。 因为您没有从日志表中提取任何列,所以您甚至也不需要连接到该表。 因为您没有聚合(如sum,count,avg等),所以不需要group by。 我认为您只是在样例查询中这样做,同时将所有数据下拉,这样就不会返回3亿行。
现在,为了更好地按时进行测试,您可能需要对一些记录最多的产品进行采样,看看单个产品记录最多的时间有多长。 为了得到它,你可能需要
SELECT
hd.product_id,
count(*) totalRecsPerProduct
FROM
hist_data_app hd
group by
hd.product_id
order by
count(*) desc
limit 10
这将得到前10个产品与最多的记录在您的3亿,然后您可以运行之前的查询对这些,看看多少实时时间得到结果回来。 我想你会看到性能是很好的去与您的单一需求的产品。