[英]REPLACE INTO table in mysql query optimization
我有以下查詢需要將近 70 分鍾才能完成。
表的記錄數:
demo.HIST_MARKETING_COMM_DISCREPANCIES -- ~400K 記錄
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 也正在使用相同的復合索引,因此保留它。 KEY 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 Break_indicator 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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.