馬桶??Java 上廁所就能看完的小知識! 歡迎關(guān)注惠豺、點(diǎn)贊 持續(xù)更新风宁!
以下文章整理自公眾號 :撿田螺的小男孩
并結(jié)合自己學(xué)習(xí)的一些規(guī)范整理而出蛹疯。當(dāng)然這只是建議因?yàn)樽髡哂X得可以提高性能
每一條建議都提供了具體實(shí)例,歡迎指正和學(xué)習(xí)哦
1. 查詢盡量不要使用SELECT *饮寞,而是SELECT具體字段
反例:
select * from employee;
正例:
select id幽崩,name from employee;
原因:
- 只取需要的字段,節(jié)省資源陌选、減少網(wǎng)絡(luò)開銷蹄溉。(因?yàn)椴樵兂鲂枰侄危揖W(wǎng)絡(luò)傳輸前后端也只傳輸需要字段役电,減少了不需要字段的開銷)
- select * 進(jìn)行查詢時(shí)棉胀,很可能就不會(huì)使用到覆蓋索引了,就會(huì)造成回表查詢瓢谢。什么是回表驮瞧?(不需要購買課程簡介足夠理解)
2.如果知道查詢結(jié)果只有一條或者只要最大/最小一條記錄论笔,建議用LIMIT 1
假設(shè)現(xiàn)在有employee員工表,要找出一個(gè)名字叫jay的人.
CREATE TABLE `employee` (
`id` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`date` datetime DEFAULT NULL,
`sex` int(1) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
反例:
select id蒜埋,name from employee where name='jay'
正例:
select id整份,name from employee where name='jay' limit 1;
原因:
- 加上limit 1后,只要找到了對應(yīng)的一條記錄,就不會(huì)繼續(xù)向下掃描了,效率將會(huì)大大提高籽孙。
- 如果name是唯一索引的話,是不必要加上limit 1了讲冠,因?yàn)閘imit的存在主要就是為了防止全表掃描适瓦,從而提高性能,如果一個(gè)語句本身可以預(yù)知不用全表掃描谱仪,有沒有l(wèi)imit 疯攒,性能的差別并不大列荔。
3.應(yīng)盡量避免在where子句中使用or來連接條件
新建一個(gè)user表,它有一個(gè)普通索引userId筷转,表結(jié)構(gòu)如下:
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userId` int(11) NOT NULL,
`age` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_userId` (`userId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
假設(shè)現(xiàn)在需要查詢userid為1或者年齡為18歲的用戶呜舒,很容易有以下sql
反例:
select * from user where userid=1 or age =18
正例:
-- 使用union all
select * from user where userid=1
union all
select * from user where age = 18
原因:
- 使用or可能會(huì)使索引失效笨奠,從而全表掃描。
- 對于or+沒有索引的age這種情況般婆,假設(shè)它走了userId的索引到腥,但是走到age查詢條件時(shí),它還得全表掃描蔚袍,也就是需要三步過程:全表掃描+索引掃描+合并 如果它一開始就走全表掃描乡范,直接一遍掃描就完事。mysql是有優(yōu)化器的啤咽,處于效率與成本考慮晋辆,遇到or條件,索引可能失效宇整,看起來也合情合理瓶佳。
4. 優(yōu)化limit分頁
我們?nèi)粘W龇猪撔枨髸r(shí),一般會(huì)用 limit 實(shí)現(xiàn)鳞青,但是當(dāng)偏移量特別大的時(shí)候,查詢效率就變得低下臂拓。
反例:
select id厚脉,name,age from employee limit 10000埃儿,10
正例:
-- 方案一 :返回上次查詢的最大記錄(偏移量) 通過索引是唯一且自增的
select id器仗,name from employee where id>10000 limit 10.
-- 方案二:order by + 索引
select id融涣,name from employee order by id limit 10000童番,10
原因:
- 當(dāng)偏移量最大的時(shí)候精钮,查詢效率就會(huì)越低,因?yàn)镸ysql并非是跳過偏移量直接去取后面的數(shù)據(jù)剃斧,而是先把偏移量+要取的條數(shù)轨香,然后再把前面偏移量這一段的數(shù)據(jù)拋棄掉再返回的。
- 如果使用優(yōu)化方案一幼东,返回上次最大查詢記錄(偏移量)臂容,這樣可以跳過偏移量,效率提升不少根蟹。
- 方案二使用order by+索引脓杉,也是可以提高查詢效率的。
5. 優(yōu)化你的like語句
日常開發(fā)中简逮,如果用到模糊關(guān)鍵字查詢球散,很容易想到like,但是like很可能讓你的索引失效散庶。
反例:
select userId蕉堰,name from user where userId like '%123';
正例:
select userId,name from user where userId like '123%';
原因:
(explain 查詢結(jié)果狀態(tài))
把%放前面悲龟,并不走索引屋讶,
把% 放關(guān)鍵字后面,還是會(huì)走索引的