成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何優(yōu)化一條SQL語句的性能?

數(shù)據(jù)庫
幾年來,我發(fā)現(xiàn)一個定律:所有SQL問題都是在凌晨三點爆發(fā)!今天抽絲剝繭,教你用架構師的思維給慢SQL開刀手術。

前言

"蘇工,訂單列表又崩了!"

接到電話時,我對著監(jiān)控大屏上999ms的SQL響應時間哭笑不得。

幾年來,我發(fā)現(xiàn)一個定律:所有SQL問題都是在凌晨三點爆發(fā)!

今天抽絲剝繭,教你用架構師的思維給慢SQL開刀手術。

希望對你會有所幫助。

1.術前檢查:找準病灶

(1)EXPLAIN 查看執(zhí)行計劃

使用EXPLAIN查看SQL語句的執(zhí)行計劃,相當于給SQL拍了張X光。

下面是一個典型的SQL問題,它是某電商平臺歷史訂單查詢的SQL語句:

SELECT * 
FROM orders o 
LEFTJOINusers u ON o.user_id = u.id
LEFTJOIN products p ON o.product_id = p.id
WHERE o.create_time > '2023-01-01'
AND u.vip_level > 3
AND p.category_id IN (5,8)
ORDERBY o.amount DESC
LIMIT1000,20;

使用EXPLAIN關鍵字查看執(zhí)行計劃的結果如下:

+----+-------------+-------+------+---------------+------+---------+------+---------+---------------------------------+
| id | select_type | table | type | possible_keys | key  | rows    | Extra| key_len | 
+----+-------------+-------+------+---------------+------+---------+------+---------+---------------------------------+
| 1  | SIMPLE      | o     | ALL  | idx_user_time | NULL | 1987400 | Using where; Using filesort     |  
| 1  | SIMPLE      | u     | ALL  | PRIMARY       | NULL | 100000  | Using where                     |
| 1  | SIMPLE      | p     | ALL  | PRIMARY       | NULL | 50000   | Using where                     |
+----+-------------+-------+------+---------------+------+---------+------+---------+---------------------------------+

診斷報告:

  • 全表掃描三連擊(type=ALL)
  • filesort暴力排序(內存警告)
  • 索引全軍覆沒

2.手術方案:精準打擊

(1)單表代謝手術

如果通過執(zhí)行計劃查到是索引有問題,我們就需要單獨優(yōu)化索引。

病根:JSON字段索引失效

錯誤用法:

ALTER TABLE users ADD INDEX idx_extend ((extend_info->'$.is_vip'));

extend_info字段是JSON類型的字段,即使創(chuàng)建了索引,索引也會丟失。

正解姿勢(MySQL 8.0+):

ALTER TABLE users ADD INDEX idx_vip_level (vip_level);
ALTER TABLE orders ADD INDEX idx_create_user (create_time, user_id) COMMENT '組合索引覆蓋查詢';

創(chuàng)建組合索引覆蓋查詢。

2.2 血管疏通術

卡點分析

原始join順序是:

orders → users → products

優(yōu)化后的方案:

(子查詢過濾users) → products → orders

調整執(zhí)行順序,用小表驅動大表。

重寫后的SQL:

SELECT o.* 
FROM products p 
INNERJOIN (
SELECT o.id, o.amount, o.create_time 
FROM orders o 
WHERE o.create_time > '2023-01-01'
) o ON p.id = o.product_id 
INNERJOIN (
SELECTid
FROMusers
WHERE vip_level > 3
) u ON o.user_id = u.id  
WHERE p.category_id IN (5,8)
ORDERBY o.amount DESC
LIMIT1000,20;

術后效果:

  • 先掃小表(users過濾后只有100條)
  • 消除冗余字段傳輸
  • 減少Join時臨時表生成

(3)開顱手術

通過執(zhí)行計劃鎖定了問題,走錯索引了,該怎么處理呢?

可以通過FORCE INDEX強制指定索引:

SELECT /*+ INDEX(o idx_create_user) */ 
       o.id, o.amount 
FROM orders o FORCE INDEX (idx_create_user)
WHERE o.create_time > '2023-01-01';

使用衍生表加速:

SELECT *
FROM (
SELECTid, amount 
FROM orders 
WHERE create_time > '2023-01-01'
ORDERBY amount DESC
LIMIT1020
) tmp 
ORDERBY amount DESC
LIMIT1000,20;

醫(yī)囑:

  • 警惕OR導致的索引失效
  • 用覆蓋索引避免回表查詢
  • CTE表達式謹慎使用

(4)生命體征監(jiān)測

查看索引使用:

SHOW INDEX FROM orders;

監(jiān)控索引使用率:

SELECT object_schema, object_name, index_name,
       count_read, count_fetch 
FROM performance_schema.table_io_waits_summary_by_index_usage
WHERE index_name IS NOT NULL;

3.術后護理:體系化治理

(1)SQL消毒中心

需要制定優(yōu)秀的代碼規(guī)范,否則可能會出現(xiàn)全表掃描的問題。

在日常工作中,我們要盡可能減少Java代碼感染源

MyBatis危險寫法:

@Select("SELECT * FROM orders WHERE #{condition}")
List<Order> findByCondition(@Param("condition") String condition);

condition參數(shù)可以傳入任何內容,如何傳入了1=1,可能會導致查詢所有的數(shù)據(jù),走全表掃描,讓查詢效率變得非常低。

正確做法(參數(shù)化查詢):

@Select("SELECT * FROM orders WHERE create_time > #{time}")
List<Order> findByTime(@Param("time") Date time);

消毒方案

  • SQL審核平臺接入(如Yearning)
  • MyBatis攔截器攔截全表更新
  • 自動化EXPLAIN分析流水線

(2)查殺大表癌癥

如果遇到大表的癌癥病例,可以用分庫分表的方案解決。

病歷案例:3億訂單表終極解決方案

// Sharding-JDBC分片配置
spring.shardingsphere.rules.sharding.tables.orders.actual-data-nodes=ds$0..1.orders_$->{2020..2023}
spring.shardingsphere.rules.sharding.tables.orders.table-strategy.standard.sharding-column=create_time
spring.shardingsphere.rules.sharding.tables.orders.table-strategy.standard.sharding-algorithm-name=time_range

化療方案:

  • 時間維度分片(2020~2023年度表)
  • 用戶ID取模分庫
  • 冷熱分離(OSS歸檔歷史數(shù)據(jù)

醫(yī)囑總結

優(yōu)化三板斧:

  • 定位:慢查詢日志+執(zhí)行計劃分析
  • 切割:化繁為簡拆分多步執(zhí)行
  • 重建:符合業(yè)務場景的數(shù)據(jù)結構

避坑口訣:

  • 索引不是銀彈,覆蓋才是王道
  • Join水深,能拆就拆
  • Order By+Limit≠分頁優(yōu)化

最后送上蘇三的傳秘方:當你優(yōu)化SQL到懷疑人生時,不妨試試這三味藥:

  • 刪業(yè)務邏輯
  • 加緩存
  • 換數(shù)據(jù)庫

保證藥到病除(老板打不打死你我就不管了,哈哈哈)!

責任編輯:姜華 來源: 蘇三說技術
相關推薦

2022-02-11 14:43:53

SQL語句C/S架構

2024-12-17 06:20:00

MySQLSQL語句數(shù)據(jù)庫

2024-01-03 17:42:32

SQL數(shù)據(jù)庫

2021-06-07 08:37:03

SQL 查詢語句

2023-03-26 22:42:02

SQL關聯(lián)索引

2025-05-20 00:00:00

2022-05-31 13:58:09

MySQL查詢語句

2025-06-04 08:20:30

2016-12-15 09:58:26

優(yōu)化SQL高性能

2017-07-12 13:04:23

數(shù)據(jù)庫SQL查詢執(zhí)行計劃

2018-09-20 11:54:31

數(shù)據(jù)庫MySQL性能優(yōu)化

2023-11-01 16:50:58

2010-11-15 14:16:09

Oracle表記錄

2021-08-30 05:47:12

MySQL SQL 語句數(shù)據(jù)庫

2011-08-02 21:16:56

查詢SQL性能優(yōu)化

2024-07-29 09:49:00

SQLMySQL執(zhí)行

2023-02-26 23:31:01

SQL數(shù)據(jù)庫

2011-08-29 16:05:07

高性能SQL語句SQL Server

2020-05-27 11:55:47

Oracle SQL性能優(yōu)化數(shù)據(jù)庫

2021-04-16 07:04:53

SQLOracle故障
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩一区二区精品 | 精品视频 免费 | 午夜视频免费网站 | 亚洲av一级毛片 | 日本不卡视频在线播放 | 国产在线视频一区 | 亚洲97| 精品国产18久久久久久二百 | 午夜视频在线播放 | 精品久久久久久久久久 | 国产美女一区二区 | 四虎影院在线免费观看 | 午夜电影一区二区 | 亚洲精品一区二区三区蜜桃久 | 色婷婷av777 av免费网站在线 | 亚洲午夜精品视频 | 国产欧美一区二区久久性色99 | 久久新视频 | 日韩精品一区二区三区中文在线 | 欧美成人综合 | 91网视频| 91视频在线 | 99久久视频 | 伊人网站在线 | 精品日韩| 久久久亚洲精品视频 | 狠狠干美女 | 国产天天操 | 精品一区二区在线视频 | 国产aa | 成人欧美一区二区三区色青冈 | 视频1区2区| 国产视频在线观看一区二区三区 | 日本亚洲欧美 | 亚洲成人一二区 | 国产我和子的乱视频网站 | 国产在线观看不卡一区二区三区 | 亚洲理论在线观看电影 | 国产精品美女久久久久久免费 | 天天操天天射天天 | www.狠狠操 |