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...