這篇文章主要介紹了MySQL優(yōu)化的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
創(chuàng)新互聯(lián)服務(wù)項目包括彝良網(wǎng)站建設(shè)、彝良網(wǎng)站制作、彝良網(wǎng)頁制作以及彝良網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,彝良網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到彝良省份的部分城市,未來相信會繼續(xù)擴大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
最近決定將以前同事寫的存儲過程查看一遍,尋找一些代碼上寫的不太好的地方,爭取進行修改以后讓這些過程達到一個很好的運行速度。下面是遇到的最多的幾個問題。
我遇到了這樣的一個SQL:
select name, count(*) from (select name from table_1) a group by a.name;
MySQL的執(zhí)行計劃對于這種派生表的解釋非常的不友好,但是能直觀的感覺到的是,這個SQL執(zhí)行速度特別的慢。查看這個表table_1發(fā)現(xiàn),name字段是有索引的。審視這段代碼,可以推斷出當(dāng)時程序員的想法,應(yīng)該是想讓數(shù)據(jù)庫掃描更小的結(jié)果集,因為select *是很不好的習(xí)慣。不過他應(yīng)該忽略了一個MySQL的很重要的特點就是索引。MySQL的索引是個很有意思的東西,是我從Oracle轉(zhuǎn)過來感覺***玩的東西,好玩的地方就在于,可以優(yōu)化group by。當(dāng)我把這個SQL改成如下SQL以后:
select name, count(*) from table_1 group by name;
這樣一來,這段SQL的執(zhí)行速度就非常的快了,extra列明確的顯示了using index,索引覆蓋查詢,速度杠杠的。
其實這種錯誤應(yīng)該是程序員常犯的,因為程序員對Java等代碼超級熟悉,但是對于SQL,基本上都是大學(xué)的時候?qū)W習(xí)的SQL,用SQLServer練出來的,基本上沒有對數(shù)據(jù)庫進行非常深入的研究,其實每種數(shù)據(jù)庫中,同一條SQL的執(zhí)行計劃都是不盡相同的,這也就是企業(yè)有一個專業(yè)的DBA的一個作用。
下面,就是一個讓人很頭疼的錯誤:
select name, userid from table_1 where name = null;
不管是MySQL還是Oracle,對這種SQL的寫法的規(guī)范都是where name is (not) null。null這個值,在不管什么數(shù)據(jù)庫里都是一個讓人(包括程序員和DBA)都很頭疼的東西。我對MySQL的理解還不夠深入,但是根據(jù)某一本《Oracle DBA手記》中記載,Oracle中每種數(shù)據(jù)類型的null都代表了不一樣的意義。
做了下面一個實驗:
可以看出來,不管是“= null”還是“<> null”,得到的值其實都是不確定,也就是null。因此,必須要寫成is (not) null。在《劍破冰山》這本書里也有對Oracle的null值的詳細介紹。
總結(jié)一下最近的工作,我研究了小半年時間的MySQL,發(fā)現(xiàn)這個開源的數(shù)據(jù)庫并不像我過去認為的那樣,就是一個互聯(lián)網(wǎng)數(shù)據(jù)庫。這個數(shù)據(jù)庫在面向OLAP復(fù)雜計算的方面確實和Oracle,DB2等商用數(shù)據(jù)庫之間有不小的差距,不過在MariaDB這個分支中,這部分有了不小的進步,相信后面的MySQL版本中也會越來越好。其實這個數(shù)據(jù)庫最讓我感興趣的不是開源,因為我確實看不懂那么長的源代碼,我的C語言水平就是大學(xué)畢業(yè)水平。這個數(shù)據(jù)庫最讓我感興趣(起碼現(xiàn)在來講)是它的索引,它的索引和Oracle有很大的不同,尤其是InnoDB的表整個就是用索引組織起來的,在簡單的查詢的時候,一個索引覆蓋查詢就可以無敵于天下了,在group by和order by的時候,如果是索引字段,效率會相當(dāng)?shù)母摺?/p>
其實我還想說的就是,一個團隊里,如果涉及到大量存儲過程的編寫,一定要有一個專業(yè)的DBA人員參與其中。SQL是一個標(biāo)準(zhǔn),橫跨了所有的關(guān)系型數(shù)據(jù)庫,但是每一種關(guān)系型數(shù)據(jù)庫對SQL的實現(xiàn)又不盡相同,因此同樣的一段SQL,放到不同的數(shù)據(jù)庫上執(zhí)行,效率上就會千差萬別。而SQL又非常容易用人最習(xí)慣最簡單的思維寫出來,比如搜索一個訂單表里美國員工生成的訂單信息,SQL有可能是這樣的:
select * from orders t1 where t1.employee_id in (select employee_id from employee t2 where t2.nation = 'USA');
如果是Oracle這樣的商業(yè)數(shù)據(jù)庫,這個SQL的執(zhí)行效率可能會比較好,但是應(yīng)該不如用exists的SQL。但是當(dāng)這段SQL在MySQL中執(zhí)行的時候,效率就很差了,因為很多人都知道,MySQL的子查詢效率實在是不敢恭維。這段代碼會被改為相關(guān)子查詢,而且隨著數(shù)據(jù)量的增長,執(zhí)行時間會越來越長。這段代碼如果改成下面的SQL,效果會更好:
select t1.* from orders t1 inner join employee t2 on t1.employee_id = t2.employee_id where t2.nation = 'USA';
如果表上有索引,執(zhí)行速度快極了。
寫SQL,還是要首先研究這個數(shù)據(jù)庫的原理,然后慎而又慎的寫。
感謝你能夠認真閱讀完這篇文章,希望小編分享的“MySQL優(yōu)化的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!