MySQL性能優化


count優化

MyISAM會將總記錄數緩存,但如果加上where條件,則緩存值失效。

若有500w條記錄,需要統計id > 100的總行數。

一個優化思路,反向操作,降低查詢次數。

select 

(select count(*) from student) - count(*) 

from student where id <= 100;

優化Limit分頁(深分頁問題)

場景模擬

插入10w條樣例數據

DROP TABLE IF EXISTS `student`;

CREATE TABLE `student` (
  `stuid` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `stuname` varchar(200) DEFAULT NULL,
  `stuaddress` varchar(200) DEFAULT NULL,
  `classid` int(11) DEFAULT NULL,
  PRIMARY KEY (`stuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DELIMITER // 
create procedure doinsert1()
begin
declare i int;
declare j int;
set i = 1;
set j = 1;
while i<100000 do
insert into student(stuid,stuname,stuaddress,classid)values(i,concat(i,'張',j),'深圳',i+j);
set i = i+1;
set j = j+1;
end while;
end;//

call doinsert1()

執行小的偏移量查詢

執行大的偏移量查詢

分析

# 打開show profile,收集在執行語句的時候所使用的資源。
SET profiling = 1;

# show profiles;
show profiles;

# 通過對應的QUERY_ID查看
show profile for query 1;

耗時最多的是Sending Data,可以看到查詢數據花了大量的時間。

優化方案一

將limit轉換為where...between


select * from student where stuid between 90002 and 90021;

優化方案二

通過where縮小范圍

如上一頁獲取到的最后的結果是90001,則下一頁則加上classid > 90001,來縮小范圍。

select * from student where classid > 90001 order by stuid limit 20;

優化方案三

從業務上進行優化,結合業務,將最大翻頁控制在指定范圍,例如最多只允許翻到100頁。

若想要獲得更多數據,需要修改關鍵詞或增加篩選條件。

優化方案四

利用覆蓋索引,先查詢指定的id,然后用inner join進行關聯。


select s.* from student s inner join  (
select stuid from student order by classid  limit 90000,20) as tmp on s.stuid = tmp.stuid;

使用變量減少查詢次數

需求是:使用分數排名,存在並列第一或第n的情況。


 create table t10( name char(10) not null default '', score int not null default 0)engine myisam charset utf8;

insert into t10 values('zhang',100),('wang',95),('li',92),('liu',100);

使用變量set @age:=20,查詢變量select @age


select name,(@curr:=score) as score,@rank:=if(@curr<>@prev,@rank:=@rank+1,@rank) as rank,@prev:=score as prev from t10 order by score desc;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM