1.如果只使用少量字段,盡量不要用select *
select * 會(huì)把數(shù)據(jù)庫(kù)所有的字段全部查詢出來(lái),浪費(fèi)內(nèi)存和CPU;
如果需要查詢的字段都是索引字段,則不要用select *,不會(huì)走覆蓋索引。
2.使用union all 不使用union
union關(guān)鍵字會(huì)進(jìn)行遍歷、排序、去重;非常耗時(shí),耗CPU
(select * from table_name where id=1)
union all
(select * from table_name where id=2);
3.小表驅(qū)動(dòng)大表
也就是說,如果查詢需要同時(shí)滿足兩張表的數(shù)據(jù),則應(yīng)該先查詢滿足小表,將滿足小表的結(jié)果集作為一個(gè)條件來(lái)查詢大表。
in 和 exists 語(yǔ)法
如果sql語(yǔ)句中包含了in關(guān)鍵字,則它會(huì)優(yōu)先執(zhí)行in里面的子查詢語(yǔ)句,然后再執(zhí)行in外面的語(yǔ)句。如果in里面的數(shù)據(jù)量很少,作為條件查詢速度更快。
而如果sql語(yǔ)句中包含了exists關(guān)鍵字,它優(yōu)先執(zhí)行exists左邊的語(yǔ)句(即主查詢語(yǔ)句)。然后把它作為條件,去跟右邊的語(yǔ)句匹配。如果匹配上,則可以查詢出數(shù)據(jù)。如果匹配不上,數(shù)據(jù)就被過濾掉了。
- in 適用于左邊大表,右邊小表。
- exists 適用于左邊小表,右邊大表。
4.批量操作
四個(gè)方面解釋:
- 1、從網(wǎng)絡(luò)傳輸方面來(lái)說,批量插入多條數(shù)據(jù),更省空間。
- 2、從連接數(shù)量來(lái)說,批量插入只使用一個(gè)連接,在使用數(shù)據(jù)庫(kù)連接池的情況下,逐個(gè)插入可能會(huì)占用多個(gè)連接。
- 3、從事務(wù)方面來(lái)說,逐條插入每次都會(huì)新建一個(gè)事務(wù),批量插入只會(huì)使用一個(gè)事務(wù)。
- 4、從日志方面來(lái)說,由于逐條插入每次都會(huì)插入binlog事務(wù)日志,也會(huì)影響效率。
5.多用limit
如果是查詢前面幾條記錄,可以通過limit num來(lái)實(shí)現(xiàn)。
6.in中的值不要太多
如果in中的值太多,可能會(huì)造成索引失效,造成接口超時(shí)。如果in 中的值確實(shí)很多,可以采用多線程去處理,分批查詢出結(jié)果后再匯總
7.增量查詢、高效的分頁(yè)查詢
如果數(shù)據(jù)量很大,分頁(yè)查詢時(shí)查詢后面的數(shù)據(jù),通過limit 100000,10去查詢,需要查詢1000010條數(shù)據(jù),再剔除前面的數(shù)據(jù),很浪費(fèi)資源。
可以通過將上一頁(yè)的最大id作為查詢的一個(gè)必須條件來(lái)查詢,每次查詢10條記錄。sql可以這樣寫
select * from table_name where id>#{lastId} limit 10
8.連表查詢代替子查詢
因?yàn)樽硬樵儓?zhí)行查詢時(shí),會(huì)創(chuàng)建一個(gè)臨時(shí)表,查詢完畢后,需要?jiǎng)h除這些臨時(shí)表,有一些額外的性能消耗。
9.join的表 不要太多
如果join太多,mysql在選擇索引的時(shí)候會(huì)非常復(fù)雜,很容易選錯(cuò)索引。
可以通過合理設(shè)計(jì)數(shù)據(jù)庫(kù)冗余字段來(lái)避免join表過多的情況。
left join和inner join
- left join:求兩個(gè)表的交集外加左表剩下的數(shù)據(jù)。
- inner join:求兩個(gè)表交集的數(shù)據(jù)。
如果兩張表使用inner join關(guān)聯(lián),mysql會(huì)自動(dòng)選擇兩張表中的小表,去驅(qū)動(dòng)大表,所以性能上不會(huì)有太大的問題。
兩張表使用left join關(guān)聯(lián),mysql會(huì)默認(rèn)用left join關(guān)鍵字左邊的表,去驅(qū)動(dòng)它右邊的表,所以使用時(shí)需要注意下。
10.索引
索引能夠顯著的提升查詢sql的性能,但是也會(huì)在增、刪、改時(shí)增加數(shù)據(jù)庫(kù)的消耗。
建立索引時(shí)不是越多越好、應(yīng)該適當(dāng)合理的建立索引。詳細(xì)參考http://www.itdecent.cn/p/7a29cd77ec7e
11.設(shè)計(jì)數(shù)據(jù)庫(kù)時(shí) 字段類型、長(zhǎng)度設(shè)計(jì)合理
我們?cè)谶x擇字段類型時(shí),應(yīng)該遵循這樣的原則:
- 能用數(shù)字類型,就不用字符串,因?yàn)樽址奶幚硗葦?shù)字要慢。
- 盡可能使用小的類型,比如:用bit存布爾值,用tinyint存枚舉值等。
- 長(zhǎng)度固定的字符串字段,用char類型。
- 長(zhǎng)度可變的字符串字段,用varchar類型。
- 金額字段用decimal,避免精度丟失問題。
12.提升group by效率
group by 時(shí)結(jié)果集應(yīng)盡量小,應(yīng)該在group by之前就通過查詢條件優(yōu)先過濾掉數(shù)據(jù)。既group by應(yīng)該在查詢條件后面
參考博客:https://zhuanlan.zhihu.com/p/431837711