1. 程式人生 > >SQL語句常見優化十大案例(MySQL)

SQL語句常見優化十大案例(MySQL)

1、慢SQL消耗了70%~90%的資料庫CPU資源;

2、SQL語句獨立於程式設計邏輯,相對於對程式原始碼的優化,對SQL語句的優化在時間成本和風險上的代價都很低;
3、SQL語句可以有不同的寫法;

下面是我總結的一些SQL常見的優化方法,每個案例都簡單易懂,在開發過程中可以作為參考:

1.不使用子查詢
例:

SELECT * FROM t1 WHERE id (SELECT id FROM t2 WHERE name='hechunyang');

子查詢在MySQL5.5版本里,內部執行計劃器是這樣執行的:先查外表再匹配內表,而不是先查內表t2,當外表的資料很大時,查詢速度會非常慢。
在MariaDB10/MySQL5.6版本里,採用join關聯方式對其進行了優化,這條SQL會自動轉換為

SELECT t1.* FROM t1 JOIN t2 ON t1.id = t2.id;

但請注意的是:優化只針對SELECT有效,對UPDATE/DELETE子查詢無效,固生產環境應避免使用子查詢

2.避免函式索引

例:

SELECT * FROM t WHERE YEAR(d) >= 2016;



由於MySQL不像Oracle那樣支援函式索引,即使d欄位有索引,也會直接全表掃描。
應改為----->

SELECT * FROM t WHERE d >= '2016-01-01';

3.用IN來替換OR

低效查詢

SELECT * FROM t WHERE LOC_ID = 10 OR LOC_ID = 20 OR LOC_ID = 30;



----->
高效查詢

SELECT * FROM t WHERE LOC_IN IN (10,20,30);

4.LIKE雙百分號無法使用到索引

SELECT * FROM t WHERE name LIKE '%de%';



----->

SELECT * FROM t WHERE name LIKE 'de%';



目前只有MySQL5.7支援全文索引(支援中文)

5、讀取適當的記錄LIMIT M,N

SELECT * FROM t WHERE 1;



----->

SELECT * FROM t WHERE 1 LIMIT 10;




6、避免資料型別不一致

SELECT * FROM t WHERE id = '19';



----->

SELECT * FROM t WHERE id = 19;




7、分組統計可以禁止排序

SELECT goods_id,count(*) FROM t GROUP BY goods_id;



預設情況下,MySQL對所有GROUP BY col1,col2...的欄位進行排序。如果查詢包括GROUP BY,想要避免排序結果的消耗,則可以指定ORDER BY NULL禁止排序。
----->

SELECT goods_id,count(*) FROM t GROUP BY goods_id ORDER BY NULL;


8、避免隨機取記錄

SELECT * FROM t1 WHERE 1=1 ORDER BY RAND() LIMIT 4;



MySQL不支援函式索引,會導致全表掃描
----->

SELECT * FROM t1 WHERE id >= CEIL(RAND()*1000) LIMIT 4;      




9、禁止不必要的ORDER BY排序

SELECT count(1) FROM user u LEFT JOIN user_info i ON u.id = i.user_id WHERE 1 = 1 ORDER BY u.create_time DESC;



----->

SELECT count(1) FROM user u LEFT JOIN user_info i ON u.id = i.user_id;




10、批量INSERT插入

  1. INSERT INTO t (id, name) VALUES(1,'Bea');

  2. INSERT INTO t (id, name) VALUES(2,'Belle');

  3. INSERT INTO t (id, name) VALUES(3,'Bernice');



----->

INSERT INTO t (id, name) VALUES(1,'Bea'), (2,'Belle'),(3,'Bernice');