日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MySQL线上优化_线上MySQL千万级大表,如何优化?

發布時間:2025/3/8 数据库 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL线上优化_线上MySQL千万级大表,如何优化? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前段時間應急群有客服反饋,會員管理功能無法按到店時間、到店次數、消費金額進行排序。經過排查發現是 SQL 執行效率低,并且索引效率低下。

圖片來自 Pexels

應急問題

商戶反饋會員管理功能無法按到店時間、到店次數、消費金額進行排序,一直轉圈圈或轉完無變化,商戶要以此數據來做活動,比較著急,請盡快處理,謝謝。

線上數據量

merchant_member_info:7000W 條數據。

member_info:3000W。

不要問我為什么不分表,改動太大,無能為力。

問題 SQL

問題 SQL 如下:

SELECT

mui.id,

mui.merchant_id,

mui.member_id,

DATE_FORMAT(

mui.recently_consume_time,

'%Y%m%d%H%i%s'

)?recently_consume_time,

IFNULL(mui.total_consume_num,?0)?total_consume_num,

IFNULL(mui.total_consume_amount,?0)?total_consume_amount,

(

CASE

WHENu.nick_nameISNULLTHEN

'會員'

WHENu.nick_name?=''THEN

'會員'

ELSE

u.nick_name

END

)?AS'nickname',

u.sex,

u.head_image_url,

u.province,

u.city,

u.country

FROM

merchant_member_info?mui

LEFTJOINmember_info?uONmui.member_id?=?u.id

WHERE

1?=?1

ANDmui.merchant_id?='商戶編號'

ORDERBY

mui.recently_consume_time?DESC/ASC

LIMIT?0,

10

出現的原因

經過驗證可以按照“到店時間”進行降序排序,但是無法按照升序進行排序主要是查詢太慢了。

主要原因是:雖然該查詢使用建立了 recently_consume_time 索引,但是索引效率低下,需要查詢整個索引樹,導致查詢時間過長。DESC 查詢大概需要 4s,ASC 查詢太慢耗時未知。

為什么降序排序快和而升序慢呢?

如下圖:

因為是對時間建立了索引,最近的時間一定在最后面,升序查詢,需要查詢更多的數據,才能過濾出相應的結果,所以慢。

解決方案

目前生產庫的索引,如下圖:

①調整索引

需要刪除 index_merchant_user_last_time 索引,同時將 index_merchant_user_merchant_ids 單例索引,變為 merchant_id,recently_consume_time 組合索引。

②調整結果(準生產)

如下圖:

③調整前后結果對比(準生產)

測試數據:

merchant_member_info 有 902606 條記錄。

member_info 表有 775 條記錄。

④SQL 執行效率

優化前,如下圖:

優化后,如下圖:

type 由 index→ref,ref 由 null→const:

調整索引需要執行的 SQL

執行的注意事項:由于表中的數據量太大,請在晚上進行執行,并且需要分開執行。

#?刪除近期消費時間索引

ALTERTABLEmerchant_member_infoDROPINDEXindex_merchant_user_last_time;

#?刪除商戶編號索引

ALTERTABLEmerchant_member_infoDROPINDEXindex_merchant_user_merchant_ids;

#?建立商戶編號和近期消費時間組合索引

ALTERTABLEmerchant_member_infoADDINDEXidx_merchant_id_recently_time?(`merchant_id`,`recently_consume_time`);

經詢問,重建索引花了 30 分鐘。

最終的分頁查詢優化

上面的 SQL 雖然經過調整索引,雖然能達到較高的執行效率,但是隨著分頁數據的不斷增加,性能會急劇下降。

最終的 SQL

優化思路:先走覆蓋索引定位到,需要的數據行的主鍵值,然后 INNER JOIN 回原表,取到其他數據。

SELECT

mui.id,

mui.merchant_id,

mui.member_id,

DATE_FORMAT(

mui.recently_consume_time,

'%Y%m%d%H%i%s'

)?recently_consume_time,

IFNULL(mui.total_consume_num,?0)?total_consume_num,

IFNULL(mui.total_consume_amount,?0)?total_consume_amount,

(

CASE

WHENu.nick_nameISNULLTHEN

'會員'

WHENu.nick_name?=''THEN

'會員'

ELSE

u.nick_name

END

)?AS'nickname',

u.sex,

u.head_image_url,

u.province,

u.city,

u.country

FROM

merchant_member_info?mui

INNERJOIN(

SELECT

id

FROM

merchant_member_info

WHERE

merchant_id?=?'商戶ID'

ORDERBY

recently_consume_time?DESC

LIMIT?9000,

10

)?AStmpONtmp.id?=?mui.id

LEFTJOINmember_info?uONmui.member_id?=?u.id

作者:不一樣的科技宅

編輯:陶家龍

出處:juejin.cn/post/6844904053239971854

【編輯推薦】

【責任編輯:武曉燕 TEL:(010)68476606】

點贊 0

總結

以上是生活随笔為你收集整理的MySQL线上优化_线上MySQL千万级大表,如何优化?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。