偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

數(shù)據(jù)庫(kù)優(yōu)化實(shí)戰(zhàn):25 個(gè) SQL 性能調(diào)優(yōu)技巧,查詢速度提升十倍

數(shù)據(jù)庫(kù)
今天這篇文章,我把壓箱底的 25 個(gè) SQL 性能調(diào)優(yōu)技巧全盤(pán)托出,每個(gè)技巧都附帶真實(shí)業(yè)務(wù)場(chǎng)景的代碼示例。

你是否遇到過(guò)這樣的情況:寫(xiě)好的 SQL 語(yǔ)句,在測(cè)試環(huán)境運(yùn)行得好好的,一到生產(chǎn)環(huán)境就 “卡成 PPT”?明明只查幾條數(shù)據(jù),卻要等上十幾秒,用戶投訴電話快被打爆,老板的臉色比鍋底還黑……

別慌!今天這篇文章,我把壓箱底的 25 個(gè) SQL 性能調(diào)優(yōu)技巧全盤(pán)托出,每個(gè)技巧都附帶真實(shí)業(yè)務(wù)場(chǎng)景的代碼示例。哪怕你是剛?cè)胄械男“?,照著做也能讓查詢速度瞬間起飛,看完記得轉(zhuǎn)發(fā)給團(tuán)隊(duì)里總被 “慢查詢” 折磨的同事!

一、索引優(yōu)化:讓查詢 “快如閃電” 的核心

1. 給過(guò)濾條件加索引,跳過(guò)全表掃描

沒(méi)加索引時(shí),查詢用戶訂單列表要掃描全表,100 萬(wàn)條數(shù)據(jù)能卡到你懷疑人生:

-- 慢查詢:無(wú)索引,全表掃描


SELECT * FROM orders WHERE user_id = 12345 AND create_time > '2025-01-01';

優(yōu)化技巧:給過(guò)濾字段建聯(lián)合索引,順序遵循 “等值在前,范圍在后”:

-- 建索引


CREATE INDEX idx_user_create ON orders(user_id, create_time);


-- 優(yōu)化后查詢(瞬間返回結(jié)果)


SELECT * FROM orders WHERE user_id = 12345 AND create_time > '2025-01-01';

2. 避免索引失效:別在索引列上做 “小動(dòng)作”

90% 的新手都會(huì)踩這個(gè)坑!在索引列上用函數(shù)或運(yùn)算,直接讓索引 “罷工”:

-- 索引失效:在索引列create_time上用函數(shù)


SELECT * FROM orders WHERE DATE(create_time) = '2025-01-01';

優(yōu)化技巧:把函數(shù)邏輯 “挪” 到等號(hào)右邊:

-- 索引生效:條件改寫(xiě)


SELECT * FROM orders WHERE create_time >= '2025-01-01 00:00:00'

AND create_time < '2025-01-02 00:00:00';

3. 用覆蓋索引,避免 “回表查詢”

如果只查幾個(gè)字段,卻用SELECT *,會(huì)導(dǎo)致數(shù)據(jù)庫(kù)先查索引,再回表取數(shù)據(jù),多走一步彎路:

-- 低效:需要回表取數(shù)據(jù)


SELECT id, user_id, amount FROM orders WHERE user_id = 12345;

優(yōu)化技巧:建 “包含查詢字段” 的覆蓋索引,直接從索引拿數(shù)據(jù):

-- 建覆蓋索引(包含查詢的所有字段)


CREATE INDEX idx_cover_user ON orders(user_id, id, amount);


-- 優(yōu)化后:索引直接返回結(jié)果,無(wú)需回表


SELECT id, user_id, amount FROM orders WHERE user_id = 12345;

二、SQL 寫(xiě)法優(yōu)化:細(xì)節(jié)決定速度

4. 用 IN 代替 OR,批量查詢更高效

當(dāng)條件字段有索引時(shí),OR會(huì)導(dǎo)致索引失效,換成IN性能提升 10 倍:

-- 低效:OR導(dǎo)致全表掃描


SELECT * FROM users WHERE id = 100 OR id = 200 OR id = 300;


-- 高效:IN走索引


SELECT * FROM users WHERE id IN (100, 200, 300);

5. 小表驅(qū)動(dòng)大表,JOIN 順序影響性能

新手寫(xiě) JOIN 時(shí)從不考慮表順序,導(dǎo)致數(shù)據(jù)庫(kù)做無(wú)用功:

-- 低效:大表在前,小表在后


SELECT * FROM orders o JOIN users u ON o.user_id = u.id

WHERE u.register_time > '2025-01-01';

優(yōu)化技巧:讓小表當(dāng) “驅(qū)動(dòng)表”(放在前面),減少循環(huán)次數(shù):

-- 高效:小表users在前,大表orders在后


SELECT * FROM users u JOIN orders o ON u.id = o.user_id

WHERE u.register_time > '2025-01-01';

6. 分頁(yè)查詢別用 OFFSET,越往后越慢

當(dāng)分頁(yè)到 1000 頁(yè)后,LIMIT 100000, 10會(huì)掃描 10 萬(wàn)行再丟棄,巨慢!

-- 低效:OFFSET越大,速度越慢


SELECT * FROM articles ORDER BY create_time DESC LIMIT 100000, 10;

優(yōu)化技巧:用 “延遲關(guān)聯(lián)”+ 索引定位,直接跳到目標(biāo)位置:

-- 高效:先查主鍵,再關(guān)聯(lián)取數(shù)據(jù)


SELECT a.* FROM articles a


JOIN (SELECT id FROM articles ORDER BY create_time DESC LIMIT 100000, 10) b


ON a.id = b.id;

三、高級(jí)優(yōu)化:從 “能用” 到 “好用”

7. 批量插入代替循環(huán)單條插入

開(kāi)發(fā)時(shí)圖方便寫(xiě)循環(huán)插入,數(shù)據(jù)庫(kù)頻繁提交事務(wù),性能差到哭:

-- 低效:?jiǎn)螚l插入,1000條要執(zhí)行1000次


INSERT INTO logs (content) VALUES ('操作1');


INSERT INTO logs (content) VALUES ('操作2');


...

優(yōu)化技巧:一次插入多條,減少 IO 次數(shù):

-- 高效:批量插入,1次搞定


INSERT INTO logs (content) VALUES

('操作1'), ('操作2'), ..., ('操作1000');

8. 用 EXPLAIN 分析 SQL,定位性能瓶頸

寫(xiě)完 SQL 別直接上線!用EXPLAIN看執(zhí)行計(jì)劃,type字段出現(xiàn)ALL就是全表掃描,必須優(yōu)化:

-- 查看執(zhí)行計(jì)劃


EXPLAIN SELECT * FROM orders WHERE user_id = 12345;

關(guān)鍵指標(biāo):

  • type:const> eq_ref> ref> range> ALL(出現(xiàn)ALL立即優(yōu)化)
  • rows:預(yù)估掃描行數(shù),越小越好
  • Extra:出現(xiàn)Using filesort(文件排序)、Using temporary(臨時(shí)表)要警惕

9. 避免在 WHERE 子句中使用函數(shù)或計(jì)算

對(duì)字段做計(jì)算會(huì)讓索引失效,比如price*0.8,數(shù)據(jù)庫(kù)無(wú)法利用price索引:

-- 低效:字段參與計(jì)算,索引失效


SELECT * FROM products WHERE price * 0.8 < 100;

優(yōu)化技巧:把計(jì)算移到等號(hào)右邊:

-- 高效:索引生效


SELECT * FROM products WHERE price < 100 / 0.8;

10. 大表拆分:水平分表 + 垂直分表

當(dāng)單表數(shù)據(jù)超過(guò) 1000 萬(wàn)行,查詢必然變慢,分表是唯一出路:

  • 水平分表:按時(shí)間拆分訂單表(orders_202501、orders_202502)
  • 垂直分表:把大字段(如content)從articles表拆分到articles_content表

11. 合理使用數(shù)據(jù)庫(kù)連接池,避免頻繁創(chuàng)建連接

頻繁創(chuàng)建和關(guān)閉數(shù)據(jù)庫(kù)連接會(huì)消耗大量資源,尤其是在高并發(fā)場(chǎng)景下:

-- 低效:每次操作都創(chuàng)建新連接


Connection conn1 = DriverManager.getConnection(url, user, password);


// 執(zhí)行操作1

conn1.close();


Connection conn2 = DriverManager.getConnection(url, user, password);


// 執(zhí)行操作2

conn2.close();

優(yōu)化技巧:使用數(shù)據(jù)庫(kù)連接池管理連接,復(fù)用連接資源:

// 初始化連接池(以HikariCP為例)

HikariConfig config = new HikariConfig();


config.setJdbcUrl(url);


config.setUsername(user);


config.setPassword(password);


config.setMaximumPoolSize(10); // 設(shè)置最大連接數(shù)

HikariDataSource dataSource = new HikariDataSource(config);


// 高效:從連接池獲取連接,用完歸還

Connection conn = dataSource.getConnection();


// 執(zhí)行操作

conn.close(); // 實(shí)際是歸還到連接池,并非真正關(guān)閉

12. 避免使用 SELECT ,只查詢需要的字段

使用SELECT *會(huì)查詢所有字段,包括不需要的字段,增加數(shù)據(jù)傳輸量和內(nèi)存消耗:

-- 低效:查詢所有字段,包括無(wú)用字段


SELECT * FROM users WHERE department_id = 5;

優(yōu)化技巧:明確指定需要查詢的字段:

-- 高效:只查詢必要字段


SELECT id, name, email FROM users WHERE department_id = 5;

13. 使用 EXISTS 代替 IN,處理子查詢更高效

當(dāng)子查詢結(jié)果集較大時(shí),IN的性能較差,EXISTS更適合:

-- 低效:子查詢結(jié)果集大時(shí),IN性能差


SELECT * FROM orders WHERE user_id IN (SELECT id FROM users WHERE status = 1);

優(yōu)化技巧:用EXISTS代替IN:

-- 高效:一旦找到匹配項(xiàng)就停止搜索


SELECT * FROM orders o WHERE EXISTS (SELECT 1 FROM users u WHERE u.id = o.user_id AND u.status = 1);

14. 控制事務(wù)范圍,避免長(zhǎng)事務(wù)

長(zhǎng)事務(wù)會(huì)占用數(shù)據(jù)庫(kù)資源,可能導(dǎo)致鎖競(jìng)爭(zhēng)和性能問(wèn)題:

-- 低效:事務(wù)范圍過(guò)大,包含無(wú)關(guān)操作


BEGIN TRANSACTION;


-- 執(zhí)行SQL操作1

-- 執(zhí)行一些耗時(shí)的非數(shù)據(jù)庫(kù)操作(如調(diào)用外部接口)


-- 執(zhí)行SQL操作2

COMMIT;

優(yōu)化技巧:縮小事務(wù)范圍,只包含必要的數(shù)據(jù)庫(kù)操作:

-- 高效:事務(wù)僅包含數(shù)據(jù)庫(kù)操作


BEGIN TRANSACTION;


-- 執(zhí)行SQL操作1

-- 執(zhí)行SQL操作2

COMMIT;


-- 執(zhí)行耗時(shí)的非數(shù)據(jù)庫(kù)操作(在事務(wù)外)

15. 為常用查詢創(chuàng)建視圖,簡(jiǎn)化復(fù)雜查詢

對(duì)于頻繁使用的復(fù)雜查詢,創(chuàng)建視圖可以提高查詢效率和代碼復(fù)用性:

-- 創(chuàng)建視圖


CREATE VIEW v_user_order_summary AS

SELECT u.id AS user_id, u.name, COUNT(o.id) AS order_count, SUM(o.amount) AS total_amount


FROM users u LEFT JOIN orders o ON u.id = o.user_id

GROUP BY u.id, u.name;


-- 高效:查詢視圖,簡(jiǎn)化操作


SELECT * FROM v_user_order_summary WHERE user_id = 123;

16. 定期清理無(wú)用數(shù)據(jù),優(yōu)化表空間

長(zhǎng)期不清理的無(wú)用數(shù)據(jù)會(huì)占用大量表空間,影響查詢性能:

-- 清理3個(gè)月前的日志數(shù)據(jù)


DELETE FROM logs WHERE create_time < DATE_SUB(NOW(), INTERVAL 3 MONTH);


-- 優(yōu)化表空間(針對(duì)InnoDB引擎)


OPTIMIZE TABLE logs;

17. 使用恰當(dāng)?shù)臄?shù)據(jù)庫(kù)引擎,提升性能

不同的數(shù)據(jù)庫(kù)引擎有不同的特點(diǎn),根據(jù)業(yè)務(wù)場(chǎng)景選擇:

  • InnoDB:支持事務(wù)、行級(jí)鎖,適合有事務(wù)需求的業(yè)務(wù),如訂單系統(tǒng)。
  • MyISAM:不支持事務(wù),支持全文索引,適合讀多寫(xiě)少的場(chǎng)景,如博客系統(tǒng)。
-- 創(chuàng)建表時(shí)指定引擎


CREATE TABLE articles (


   id INT PRIMARY KEY AUTO_INCREMENT,


   title VARCHAR(255),


   content TEXT

) ENGINE=MyISAM;

18. 合理設(shè)置數(shù)據(jù)庫(kù)參數(shù),優(yōu)化配置

根據(jù)服務(wù)器配置和業(yè)務(wù)需求,調(diào)整數(shù)據(jù)庫(kù)參數(shù)可以提升性能,以 MySQL 為例:

-- 在my.cnf或my.ini中配置


innodb_buffer_pool_size = 4G  # 設(shè)置InnoDB緩沖池大小,一般為服務(wù)器內(nèi)存的50%-70%


query_cache_size = 64M  # 設(shè)置查詢緩存大小,適合讀多寫(xiě)少的場(chǎng)景


max_connections = 1000  # 最大連接數(shù),根據(jù)并發(fā)量設(shè)置

19. 避免在循環(huán)中執(zhí)行 SQL,減少交互次數(shù)

在循環(huán)中執(zhí)行 SQL 會(huì)增加與數(shù)據(jù)庫(kù)的交互次數(shù),降低性能:

-- 低效:循環(huán)中執(zhí)行SQL

for (User user : userList) {


   String sql = "INSERT INTO users (name) VALUES ('" + user.getName() + "')";


   // 執(zhí)行SQL

}

優(yōu)化技巧:使用批量操作或拼接 SQL 語(yǔ)句(注意 SQL 注入問(wèn)題):

-- 高效:批量插入


INSERT INTO users (name) VALUES

<foreach collection="userList" item="user" separator=",">


   (#{user.name})


</foreach>

20. 使用數(shù)據(jù)庫(kù)緩存,減少重復(fù)查詢

對(duì)于不經(jīng)常變化的數(shù)據(jù),使用數(shù)據(jù)庫(kù)緩存可以減少數(shù)據(jù)庫(kù)訪問(wèn)次數(shù):

-- 開(kāi)啟查詢緩存(MySQL 8.0已移除查詢緩存,可使用應(yīng)用級(jí)緩存如Redis)


-- 在MySQL配置文件中設(shè)置


query_cache_type = ON

-- 執(zhí)行查詢后,結(jié)果會(huì)被緩存


SELECT * FROM categories;

21. 避免使用 NULL 作為查詢條件,影響索引使用

NULL值可能導(dǎo)致索引失效,盡量使用有意義的默認(rèn)值:

-- 低效:使用IS NULL,可能導(dǎo)致索引失效


SELECT * FROM products WHERE discount IS NULL;

優(yōu)化技巧:設(shè)置默認(rèn)值,如用 0 表示無(wú)折扣:

-- 高效:使用默認(rèn)值,可利用索引


SELECT * FROM products WHERE discount = 0;

22. 對(duì)大文本字段進(jìn)行壓縮存儲(chǔ),節(jié)省空間

對(duì)于大文本字段(如 TEXT 類型),壓縮后存儲(chǔ)可以減少存儲(chǔ)空間和 IO 操作:

-- 插入時(shí)壓縮


INSERT INTO articles (title, content) VALUES ('標(biāo)題', COMPRESS('大量的文本內(nèi)容...'));


-- 查詢時(shí)解壓


SELECT title, UNCOMPRESS(content) AS content FROM articles WHERE id = 1;

23. 合理使用分區(qū)表,提高大表查詢效率

對(duì)于數(shù)據(jù)量大的表,使用分區(qū)表可以將數(shù)據(jù)分散到多個(gè)分區(qū),提高查詢效率:

-- 創(chuàng)建按時(shí)間分區(qū)的訂單表


CREATE TABLE orders (


   id INT PRIMARY KEY,


   order_no VARCHAR(50),


   create_time DATETIME

) PARTITION BY RANGE (TO_DAYS(create_time)) (


   PARTITION p202501 VALUES LESS THAN (TO_DAYS('2025-02-01')),


   PARTITION p202502 VALUES LESS THAN (TO_DAYS('2025-03-01')),


   PARTITION p202503 VALUES LESS THAN (TO_DAYS('2025-04-01'))


);

24. 避免使用存儲(chǔ)過(guò)程和觸發(fā)器,減少數(shù)據(jù)庫(kù)壓力

存儲(chǔ)過(guò)程和觸發(fā)器邏輯復(fù)雜時(shí),會(huì)增加數(shù)據(jù)庫(kù)負(fù)擔(dān),可移至應(yīng)用層處理:

-- 不推薦:復(fù)雜的存儲(chǔ)過(guò)程


CREATE PROCEDURE complex_procedure()


BEGIN

   -- 大量復(fù)雜邏輯


END;

優(yōu)化技巧:在應(yīng)用層實(shí)現(xiàn)相應(yīng)邏輯:

// 應(yīng)用層處理邏輯,減輕數(shù)據(jù)庫(kù)壓力

public void handleComplexLogic() {


   // 實(shí)現(xiàn)原存儲(chǔ)過(guò)程中的邏輯

}

25. 定期分析表,更新統(tǒng)計(jì)信息

數(shù)據(jù)庫(kù)優(yōu)化器需要準(zhǔn)確的統(tǒng)計(jì)信息來(lái)生成最優(yōu)執(zhí)行計(jì)劃,定期分析表可以更新統(tǒng)計(jì)信息:

-- 分析表,更新統(tǒng)計(jì)信息(MySQL)


ANALYZE TABLE orders;


-- PostgreSQL中


ANALYZE orders;

為什么這些技巧能讓查詢速度提升 10 倍?

數(shù)據(jù)庫(kù)性能瓶頸 90% 出在 “不必要的掃描” 和 “低效的索引使用” 上。上面的技巧看似簡(jiǎn)單,卻直擊痛點(diǎn):

  • 索引優(yōu)化減少 90% 的掃描行數(shù)
  • SQL 寫(xiě)法優(yōu)化避免數(shù)據(jù)庫(kù)做無(wú)用功
  • 批量操作降低 IO 次數(shù),減少事務(wù)開(kāi)銷

最后提醒:優(yōu)化不是一次性工作,上線后要持續(xù)監(jiān)控慢查詢?nèi)罩荆ㄩ_(kāi)啟slow_query_log),定期用pt-query-digest分析 TOP10 慢 SQL,讓數(shù)據(jù)庫(kù)永遠(yuǎn) “飛” 起來(lái)!

責(zé)任編輯:趙寧寧 來(lái)源: 編程江湖
相關(guān)推薦

2025-10-10 05:56:11

2023-11-10 09:25:36

Oracle數(shù)據(jù)庫(kù)

2024-06-27 11:22:34

2024-11-11 08:11:39

2025-06-05 04:22:00

SQL性能索引

2017-09-26 14:56:57

MongoDBLBS服務(wù)性能

2023-04-03 10:25:00

數(shù)據(jù)庫(kù)性能調(diào)優(yōu)

2023-09-11 08:38:38

Oracle數(shù)據(jù)庫(kù)

2023-09-07 11:29:36

API開(kāi)發(fā)

2025-05-26 00:02:00

TypeScriptGo 語(yǔ)言前端

2011-08-15 18:09:46

查詢性能調(diào)優(yōu)索引優(yōu)化

2017-12-05 13:41:02

SQL數(shù)據(jù)庫(kù)SQL查詢

2019-03-27 13:45:44

MySQL優(yōu)化技巧數(shù)據(jù)庫(kù)

2009-07-06 21:20:34

SQL Server數(shù)

2011-07-08 16:02:54

HBase

2023-09-25 13:15:50

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

2012-11-21 17:35:21

Oracle技術(shù)嘉年華

2023-02-07 08:00:00

MySQL數(shù)據(jù)庫(kù)技巧

2023-06-13 13:52:00

Java 7線程池

2024-11-01 07:30:00

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)