本文主要從工作經驗中總結出來的經驗總結sql語句優化問題,下面我們用Demo來具體說明如何提高sql的執行效率:
1、關于limit分頁優化的問題
SELECT * FROM message_1 LIMIT 10000,10
這條語句執行速度很快,當我們把語句改成下面語句的時候再看看用了多久?
SELECT * FROM message_1 LIMIT 1000000,10
運行結果如下圖:
上面的語句整整用了17.7秒!這么慢,用戶可是等不了了,那么我們如何優化這句sql呢?
解決方法:
我們加“order by id”改造后的sql為:
SELECT * FROM message_1 order by id LIMIT 1000000,10
執行圖如下:
只用了1.1秒,可以說稍微改動一下,效率提升了17倍。這是因為這個sql語句使用了主鍵id來作為索引,所以速度很快。
2、任何情況下都禁止使用 select * from table
因為這樣會進行全表掃描而導致效率很低
SELECT * FROM message_1
應改為
SELECT content FROM message_1
3、優化批量插入
INSERT INTO message_1(id,content) values(1,'內容1')
INSERT INTO message_1(id,content) values(2,'內容2')
INSERT INTO message_1(id,content) values(3,'內容3')
INSERT INTO message_1(id,content) values(4,'內容4')
INSERT INTO message_1(id,content) values(5,'內容5')
應改為
INSERT INTO message_1(id,content) values(1,'內容1'),(2,'內容2'),(3,'內容3'),(4,'內容4'),(5,'內容5')
4、like語句的優化
SELECT content message_1 A WHERE content like '%我要學習%'
like后面使用了“%”,所以該sql語句查詢會進行全表掃描,使索引失效,因此速度會很慢,如果想走索引的話,可以改下下面的語句:
SELECT content FROM message_1 WHERE content like '我要學習%'
5、避免where語句中使用IS NULL或IS NOT NULL語句
SELECT content FROM message_1 WHERE content IS NULL
上面的語句同樣會使索引失效而進行全表掃描,我們在where語句中避免使用 IS NULL或者IS NOT NULL來進行條件選擇,這樣做會使索引失效,從而導致查詢速度很慢
6、不要在where條件中出現函數、算數運算或其他表達式運算
SELECT content FROM message_1 WHERE datediff(day,createTime,'2020-05-25')=0
改為
SELECT content FROM message_1 WHERE createTime>='2020-05-01' and createTime<'2020-05-25'
這句話告訴我們不要在where條件中出現函數、算數運算或其他表達式運算,否則也會使索引失效。
7、排序的索引問題
如果MySQL查詢語句中只用了一個索引,而where條件中已經使用了索引,則order by中的字段就不會使用索引。因此盡量不要同時對多個字段進行排序,如果有這樣的場景存在的話,那最好給這些字段設置聯合索引。
8、union all替換union
union和union all的區別在于前者需要合并兩個以上的結果集,然后在進行唯一性過濾操作,這樣做肯定會涉及到數據的排序,增大cpu的運算與資源消耗和延遲。因此,當在確定沒有重復數據或者不關心重復數據的情況下,要使用union all。
9、left joinright join和inner join
SELECT A.id,A.name,B.id,B.name FROM message_1 LEFT JOIN message_2 b ON b.id =B.id;
SELECT A.id,A.name,B.id,B.name FROM message_1 RIGHT JOIN message_2 b ON B A.id= B.id;
SELECT A.id,A.name,B.id,B.name FROM message_1 INNER JOIN message_2 b ON A.id =B.id;
上面的語句運行后發現inner join運行速度比較快,因為inner join是等值連接,返回的行數比較少。所以在項目開發過程中最好使用inner join
10、索引的數量控制在5個以內
因為不是索引越多就越好。索引盡管提高了查詢效率,但是也是降低修改和新增的效率。而且insert和update有重建索引的可能,所以一張表的索引數最好不要超過五個,如果超過五個那么就得針對這張表做優化處理了