Mysql的優化例項

2021-10-23 00:17:44 字數 4112 閱讀 3952

1.建立乙個課程表

create table course(

c_id int primary key,

name varchar(10)

)

2.建立乙個學生表

create table student(

s_id int primary key,

name varchar(10)

)

3.建立乙個課程學生表

create table sc(

sc_id int primary key,

s_id int,

c_id int,

score int

)

4.通過儲存過程 插入七十萬的資料

delimiter $$

create procedure insert_dept(in start int(10),in max_num int(10))

begin

declare i int default 0;

set autocommit = 0;

repeat

set i=i+ 1;

insert into course(c_id ,name) values ((start+i),concat("語文"));

until i = max_num

end repeat;

commit;

end $$

delimiter $$

create procedure insert_dept(in start int(10),in max_num int(10))

begin

declare i int default 0;

set autocommit = 0;

repeat

set i=i+ 1;

insert into student(id ,name) values (start+i,(concat("小明",i)));

until i = max_num

end repeat;

commit;

end $$

呼叫這連兩個過程,插入資料

5.查詢語文成績為89的學生資訊

select * from student s where s.s_id in (select sc.s_id from sc sc where sc.score = 89 and sc.c_id = 1)
執行後發現時間要的很久,我直接停止查詢了

然後我們建立索引,提高查詢速度

存在全表掃瞄,速度太慢了

檢視一下mysql的處理執行器優化過後的sql

在explain extended 後執行show warning

explain extended select * from student s where s.s_id in (select sc.s_id from sc sc where sc.score = 89 and sc.c_id = 1);

show warnings

可以看到mysql優化器優化後的sql
select

`crm`.`s`.`s_id` as `s_id`,

`crm`.`s`.`name` as `name`

from

`crm`.`student` `s`

where

< in_optimizer > (

`crm`.`s`.`s_id` ,< exists > (

select

1from

`crm`.`sc`

where

((`crm`.`sc`.`c_id` = 1)

and (`crm`.`sc`.`score` = 89)

and (

< cache > (`crm`.`s`.`s_id`) = `crm`.`sc`.`s_id`))

) )

可以看到mysql 經過優化後 將in修改為exists

select count(1) from sc sc where sc.score = 89 and sc.c_id = 1

:1162

這個不符合exists後接大表的原則,需要迴圈700000*1162次

所以可以通過連表查詢:

select * from student s inner join sc sc on s.s_id = sc.sc_id where sc.score = 89 and sc.c_id = 1
這樣的話,速度快了很多 0.416s

檢視執行計畫:

還是有可以優化的空間

檢視一下優化過後的sql

select

`crm`.`s`.`s_id` as `s_id`,

`crm`.`s`.`name` as `name`,

`crm`.`sc`.`sc_id` as `sc_id`,

`crm`.`sc`.`s_id` as `s_id`,

`crm`.`sc`.`c_id` as `c_id`,

`crm`.`sc`.`score` as `score`

from

`crm`.`student` `s`

join `crm`.`sc`

where

( (

`crm`.`s`.`s_id` = `crm`.`sc`.`sc_id`

) and (`crm`.`sc`.`c_id` = 1)

and (`crm`.`sc`.`score` = 89)

)

先連表在去通過where條件過濾,還是很大,可以先將sc表中過濾後再去連表

select s.* from (select sc.s_id from sc sc where sc.score = 89 and sc.c_id = 1) t inner join student s on s.s_id = t.s_id
這樣子以後,速度更快了0.121s

檢視執行計畫

這裡用到了intersect 這樣並集操作,就是兩個索引同事檢索,然後再求並集

在看score 和c_id這兩個字段,區分度不高,我們可以建立聯合索引,也可以提交高區分度

create index ind_sc_score_id on sc(score,s_id)
刪除之前的索引,然後執行後發現 0.056s快了一倍

這樣還可以了

總結:列型別盡量定義成數值型別,且長度盡可能短,如主鍵和外來鍵,型別字段等等

建立單列索引

根據需要建立多列聯合索引

當單個列過濾之後還有很多資料,那麼索引的效率將會比較低,即列的區分度較低,

那麼如果在多個列上建立索引,那麼多個列的區分度就大多了,將會有顯著的效率提高。

根據業務場景建立覆蓋索引

只查詢業務需要的字段,如果這些欄位被索引覆蓋,將極大的提高查詢效率

多表連線的字段上需要建立索引

這樣可以極大的提高表連線的效率

where條件欄位上需要建立索引

排序欄位上需要建立索引

分組欄位上需要建立索引

where條件上不要使用運算函式,以免索引失效

MySQL優化例項

在apache,php,mysql的體系架構中,mysql對於效能的影響最大,也是關鍵的核心部分。對於discuz 論壇程式也是如此,mysql的設定是否合理優化,直接影響到論壇的速度和承載量!同時,mysql也是優化難度最大的乙個部分,不但需要理解一些mysql專業知識,同時還需要長時間的觀察統計...

MySQL優化例項

mysql優化例項 在apache,php,mysql的體系架構中,mysql對於效能的影響最大,也是關鍵的核心部分。對於discuz 論壇程式也是如此,mysql的設定是否合理優化,直接 影響到論壇的速度和承載量!同時,mysql也是優化難度最大的乙個部分,不但需要理解一些mysql專業知識,同時...

mysql優化例項

1.查詢所有欄位的sql耗時 0.003497 秒 2.查詢所需欄位sql耗時 limit 3 0.001194 秒 select group sn,small desc,group name,end time,group image,already orders already orders vi...