mysql百萬級數(shù)據(jù)查詢優(yōu)化:快速定位當(dāng)日數(shù)據(jù)
在處理百萬級MySQL數(shù)據(jù)時,高效檢索特定日期的數(shù)據(jù)至關(guān)重要。本文通過一個案例分析,探討如何優(yōu)化查詢語句,提升查詢效率。案例中,bns_pm_scanhistory_month表包含約一百萬條記錄,目標(biāo)是快速查詢scantime字段(datetime類型)為當(dāng)天(例如2023年2月6日)的數(shù)據(jù)。
最初的查詢語句使用date_format函數(shù):
select * from bns_pm_scanhistory_month where date_format(scantime, '%y%m%d') ='20230206'
該語句執(zhí)行時間約為16秒。 隨后嘗試使用BETWEEN運(yùn)算符:
select * from bns_pm_scanhistory_month where scantime between '2023-02-06 00:00:00' and '2023-02-06 23:59:59';
令人費(fèi)解的是,執(zhí)行時間反而增加至20秒。 雖然scantime字段已建立索引:
index `scantime_index`(`scantime`) using btree,
但date_format函數(shù)的使用導(dǎo)致索引失效。MySQL無法直接利用索引,只能進(jìn)行全表掃描,從而導(dǎo)致查詢緩慢。BETWEEN語句雖然直接使用scantime字段,但效率仍然低下,這可能與數(shù)據(jù)分布不均或其他索引沖突有關(guān)。
根本原因在于date_format(scantime, ‘%y%m%d’) 對索引字段進(jìn)行了函數(shù)計(jì)算,阻止了索引的有效利用。對于百萬級數(shù)據(jù),全表掃描代價巨大。因此,應(yīng)避免在WHERE條件中對索引字段使用函數(shù)。
優(yōu)化策略:直接使用日期范圍比較,并驗(yàn)證索引是否生效。可以使用EXPLaiN語句分析查詢計(jì)劃,檢查索引使用情況。如果索引失效,則需檢查索引創(chuàng)建是否正確,是否存在隱式類型轉(zhuǎn)換或其他條件與索引不匹配的情況。百萬級數(shù)據(jù)量不算龐大,如此低的查詢效率表明存在索引失效或其他問題。
更有效的查詢方式:
SELECT * FROM bns_pm_scanhistory_month WHERE ScanTime >= '2023-02-06 00:00:00' AND ScanTime < '2023-02-07 00:00:00';
此語句避免函數(shù)計(jì)算,充分利用scantime索引,顯著提升查詢效率。 BETWEEN語句效率低下的原因需要結(jié)合EXPLAIN結(jié)果和數(shù)據(jù)庫配置進(jìn)行進(jìn)一步分析。