本文總結了一些工作常見的sql優化例子,雖然比較簡單,但很實用,希望對大家有所幫助。sql優化一般分為兩類,一類是sql本身的優化,如何走到合適的索引,如何減少排序,減少邏輯讀;另一類是sql本身沒有優化餘地,需要結合業務場景進行優化。即在滿足業務需求的情況下對sql進行改造,已提高sql執行速度,減少響應時間。
例子1:
select id from sendlog where to_days(now())-to_days(gmt_create) > 7;
問題:對索引列gmt_create進行了運算,無法使用索引
優化後sql:
例子2:
問題:result列含有索引,但mysql執行計畫沒有用到。
分析:result型別為char,傳遞的值1為整型,資料型別不一致,導致沒法用索引,對於時間型別gmt_create > '2013-10-29 12:40:44',可以直接使用。
優化後sql:
例子3:
場景:獲取某個賣家未讀的訊息。
select count(*) from mc_msg where receiver='sun098' and status='unread' and title is not null;
問題:有時候db負載飆高,sql響應時間變慢。
分析:導致db負載飆高的原因是多個大賣家併發查詢的時,
cpu和邏輯讀增加,
load
飆高。由於receiver,status已有索引,sql本身已經沒有優化空間,
了解業務後發現其實業務不需要精確值,如果大於
99條,頁面就直接顯示為
99+優化後
sql:
select count(*) from (select id from mc_msg where receiver='sun098' and status='unread' and title is not null limit 100) a;
例子4:
select * from(
select id,gmt_create,gmt_modified,sender_ali_id,receiver_ali_id,unread_count,status,last_message_id,relation_id,seller_admin_seq,is_read
from message_relation_sender
where sender_ali_id = 119545671 and unread_count > 0
order by last_message_id desc) m
union all
select * from(
select id,gmt_create,gmt_modified,sender_ali_id,receiver_ali_id,unread_count,status,last_message_id,relation_id,seller_admin_seq,is_read from message_relation_sender
where sender_ali_id = 119545671 and unread_count = 0
order by last_message_id desc) n limit 5000,15;
分析:(4)limit 5000,15是分頁查詢
優化:這裡看到unread_count實際值對這個查詢沒有實際意義,我們只需要區分已讀和未讀即可。由於sql本身已經沒有優化餘地,考慮對錶結構進行修改,加乙個欄位is_read,表示已讀和未讀。is_read=2表示未讀;is_read=1表示已讀。通過組合索引(sender_ali_id,is_read, last_message_id),既可以完成過濾,還可以完成排序。
優化後sql:
select id,gmt_create,gmt_modified,sender_ali_id,receiver_ali_id,unread_count,status,last_message_id,relation_id,seller_admin_seq,is_read from message_relation_sender
where sender_ali_id = 119545671 order by is_read desc, last_message_id desc limit 5000,15
第二次優化:
由於索引不包含所有的返回字段,因此需要回表,而mysql對於limit 5000,15的查詢卻需要返回5015次,這種無效的返回很影響查詢效率。
分頁的優化寫法:
select t1.id,gmt_create,gmt_modified,sender_ali_id,receiver_ali_id,unread_count,status,last_message_id,relation_id,seller_admin_seq,is_read from message_relation_sender t1,
(select id
from message_relation_sender
where sender_ali_id = 119545671 order by is_read desc, last_message_id desc limit 5000,15
)t2 where t1.id = t2.id
分析:由於id是主鍵,不需要回表,通過連線查詢,最終只需要15次回表即可。
mysql優化案例
1 使用join還是子查詢 select from employee left join test on test.id employee.id select employee.select id from test where test.id employee.id t from employee...
MySQL索引優化案例
開發同學或多或少會遇到系統響應慢的問題,除了業務系統本身的問題外,常常會遇到sql查詢慢的問題,這篇文章結合實際案例分析mysql innodb儲存引擎的索引優化,這篇文章不會介紹b 樹的知識點,如果需要了解聚集索引和輔助索引特點的同學可以參考這篇文章,這篇文章主要會介紹三星索引和icp優化.首先是...
MySql索引優化案例
建立新錶 create table article id int unsigned not null primary key auto increment,author id int unsigned not null,category id int unsigned not null,views ...