如何解决mysql查询优化中的REPLACE INTO表
我在下面有一个查询,需要大约70分钟才能完成。
表的记录数:
-
demo.HIST_MARKETING_COMM_DISCREPANCIES-约40万条记录
-
demo.VW_2AND3_LETTER_COUNTRY_DETAILS-260条记录
-
DG_ORG_DETAILS_DIM-20条记录
我的MySQL服务器配置:2个vCPU,6GB RAM,300GB磁盘大小
replace into demo.mt_mkt_comm_base_tbl
SELECT c.org_id,c.org_name,IFNULL(GETINITCAP(hcd.cntry_name),a.prmry_reside_country_code) country_name,a.*
FROM demo.hist_marketing_comm_discrepancies a
LEFT
JOIN demo.vw_2and3_letter_country_details hcd
ON hcd.cntry_code2 = a.prmry_reside_country_code
LEFT
JOIN demo.dg_org_details_dim c
ON a.org_id = c.org_id
WHERE a.active_flag = 'y'
AND a.breach_indicator IS NOT NULL
解释以上内容的计划:
寻求一些帮助提高查询性能的方法,我什至可以扩展我的服务器配置。
我使用了以下索引
-
在hist_marketing_comm_discrepancies中的(ACTIVE_FLAG,BREACH_INDICATOR,MAIL_DATE)上的复合索引,即使MAIL_DATE也被删除,也正在使用相同的复合索引,因此请保留它。 密钥
idx_composite_key
(ACTIVE_FLAG
,BREACH_INDICATOR
,MAIL_DATE
) -
CNTRY_CODE2上的索引
-
ORG_ID上的索引
现在的解释计划如下
查询给出的结果约为20分钟,反正查询执行时间会进一步减少。
我调整了innodb_buffer_pool_size的大小, 修改之前是108M,我已经将其修改为3000M,现在整个替换查询在大约2分钟内完成。
要更改设置,请在my.cnf文件的[mysqld]部分中完成。并且必须重新启动mysqld才能使其生效。 (在ubuntu中,您可以在/ etc文件夹中找到my.cnf文件)
解决方法
确保所有这些字段都已索引: cntry_code2 prmry_reside_country_code org_id 违反指标 active_flag 它将减少您的问题的基数。 删除IFNULL并随后过滤查询。 确保可以扩展服务器,但配置和数据量不会太慢。
,让我们备份一步。 REPLACE
的目的是什么?有多少张桌子要更换?
如果构建表的新副本是可行的,则将其“交换”到位,这可能会更快。 (参见RENAME TABLE
;如有需要,我可以进一步讨论。)
如果逐个进行“替换”是可行的,那么它的侵入性可能会大大降低。 (请参见http://mysql.rjweb.org/doc.php/deletebig#deleting_in_chunks中的技术)
请注意,REPLACE
被实现为DELETE
+ INSERT
。这样,您破坏了auto_inc值,并且比使用IODKU更加努力,所以...
如果您坚持使用REPLACE .. SELECT ..
,请考虑更改为INSERT INTO t .. ON DUPLICATE KEY UPDATE ..
。它可能会更快。
http://mysql.rjweb.org/doc.php/deletebig#optimal_reload_of_a_table讨论了全表替换和RENAME TABLE
的用法。
索引
这些可能会帮助一些人
a: (active_flag,breach_indicator,org_id,prmry_reside_country_code)
c: (org_id,org_name)
hcd: (cntry_code2,cntry_name)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。