本文中講解的內(nèi)容 sql各語(yǔ)句執(zhí)行順序概覽與講解 項(xiàng)目實(shí)戰(zhàn)中的一段sql說明講解 sql語(yǔ)句中別名的使用 書寫sql語(yǔ)句的注意事項(xiàng) 上一篇講Mysql基本架構(gòu)時(shí),以“sql查詢語(yǔ)句在MySql架構(gòu)中具體是怎么執(zhí)行的?”進(jìn)行了全面的講解。知道了sql查詢語(yǔ)句在MySql架構(gòu)中的具體執(zhí)行流程,但是為了能夠更好更快的寫出sql語(yǔ)句,我覺得非常有必要知道sql語(yǔ)句中各子句的執(zhí)行順序??催^上一篇文章的小伙伴應(yīng)該都知道,sql語(yǔ)句最后各子句的執(zhí)行應(yīng)該是在執(zhí)行器中完成的,存儲(chǔ)引擎對(duì)執(zhí)行器提供的數(shù)據(jù)讀寫接口?,F(xiàn)在開始我們的學(xué)習(xí) 語(yǔ)句中各子句完整執(zhí)行順序概括(按照順序號(hào)執(zhí)行)
每個(gè)子句執(zhí)行順序分析所有的 查詢語(yǔ)句都是從from開始執(zhí)行的,在執(zhí)行過程中,每個(gè)步驟都會(huì)為下一個(gè)步驟生成一個(gè)虛擬表,這個(gè)虛擬表將作為下一個(gè)執(zhí)行步驟的輸入。 1. fromform是一次查詢語(yǔ)句的開端。
2. join如果from后面是多張表,join關(guān)聯(lián),會(huì)首先對(duì)前兩個(gè)表執(zhí)行一個(gè)笛卡爾乘積,這時(shí)候就會(huì)生成第一個(gè)虛擬表T1(注意:這里會(huì)選擇相對(duì)小的表作為基礎(chǔ)表); 3. on對(duì)虛表T1進(jìn)行ON篩選,只有那些符合 4. where對(duì)虛擬表T2進(jìn)行WHERE條件過濾。只有符合 5.group bygroup by 子句將中的唯一的值組合成為一組,得到虛擬表T4。如果應(yīng)用了group by,那么后面的所有步驟都只能操作T4的列或者是執(zhí)行6.聚合函數(shù)(count、sum、avg等)。(注意:原因在于分組后最終的結(jié)果集中只包含每個(gè)組中的一行。謹(jǐn)記,不然這里會(huì)出現(xiàn)很多問題,下面的代碼誤區(qū)會(huì)特別說。) 6. avg,sum.... 等聚合函數(shù)聚合函數(shù)只是對(duì)分組的結(jié)果進(jìn)行一些處理,拿到某些想要的聚合值,例如求和,統(tǒng)計(jì)數(shù)量等,并不生成虛擬表。 7. having應(yīng)用having篩選器,生成T5。HAVING子句主要和GROUP BY子句配合使用,having篩選器是第一個(gè)也是為唯一一個(gè)應(yīng)用到已分組數(shù)據(jù)的篩選器。 8. select執(zhí)行select操作,選擇指定的列,插入到虛擬表T6中。 9. distinct對(duì)T6中的記錄進(jìn)行去重。移除相同的行,產(chǎn)生虛擬表T7.(注意:事實(shí)上如果應(yīng)用了group by子句那么distinct是多余的,原因同樣在于,分組的時(shí)候是將列中唯一的值分成一組,同時(shí)只為每一組返回一行記錄,那么所以的記錄都將是不相同的。) 10. order by應(yīng)用order by子句。按照order_by_condition排序T7,此時(shí)返回的一個(gè)游標(biāo),而不是虛擬表。sql是基于集合的理論的,集合不會(huì)預(yù)先對(duì)他的行排序,它只是成員的邏輯集合,成員的順序是無(wú)關(guān)緊要的。對(duì)表進(jìn)行排序的查詢可以返回一個(gè)對(duì)象,這個(gè)對(duì)象包含特定的物理順序的邏輯組織。這個(gè)對(duì)象就叫游標(biāo)。
11. limit取出指定行的記錄,產(chǎn)生虛擬表T9, 并將結(jié)果返回。 limit后面的參數(shù)可以是 一個(gè)limit m ,也可以是limit m n,表示從第m條到第n條數(shù)據(jù)。 (注意:很多開發(fā)人員喜歡使用該語(yǔ)句來解決分頁(yè)問題。對(duì)于小數(shù)據(jù),使用LIMIT子句沒有任何問題,當(dāng)數(shù)據(jù)量非常大的時(shí)候,使用LIMIT n, m是非常低效的。因?yàn)長(zhǎng)IMIT的機(jī)制是每次都是從頭開始掃描,如果需要從第60萬(wàn)行開始,讀取3條數(shù)據(jù),就需要先掃描定位到60萬(wàn)行,然后再進(jìn)行讀取,而掃描的過程是一個(gè)非常低效的過程。所以,對(duì)于大數(shù)據(jù)處理時(shí),是非常有必要在應(yīng)用層建立一定的緩存機(jī)制) 開發(fā)某需求寫的一段sqlSELECT `userspk`.`avatar` AS `user_avatar`,
想要查詢pk記錄表中分?jǐn)?shù)最高的9個(gè)用戶記錄和他們的頭像。 查詢結(jié)果:
pk記錄表的數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì),每個(gè)用戶每天每個(gè)館下可能會(huì)有多條記錄,所以需要進(jìn)行分組,并且查詢結(jié)果只想拿到每個(gè)分組內(nèi)最高的那條記錄。 這段sql的一些說明:
看一下代碼和執(zhí)行結(jié)果與帶有子查詢的進(jìn)行比較,不帶子查詢的查詢結(jié)果的確查到的最大分?jǐn)?shù)與子查詢的最大分?jǐn)?shù)相同,但是根據(jù)id確認(rèn)二者并不是同一條記錄??唇Y(jié)果是不是就能理解我上面說的一段話 查詢結(jié)果: 2. 在子查詢中對(duì)數(shù)據(jù)已經(jīng)進(jìn)行排序后,外層排序方式如果和子查詢排序分?jǐn)?shù)相同,都是分?jǐn)?shù)倒序,外層的排序可以去掉,沒有必要寫兩遍。 sql語(yǔ)句中的別名別名在哪些情況使用在 SQL 語(yǔ)句中,可以為表名稱及字段(列)名稱指定別名
同時(shí)查詢兩張表的數(shù)據(jù)的時(shí)候:未設(shè)置別名前: SELECT article.title,article.content,user.username FROM article, user設(shè)置別名后: 好處:使用表別名查詢,可以使 SQL 變得簡(jiǎn)潔而更易書寫和閱讀,尤其在 SQL 比較復(fù)雜的情況下
查詢一張表,直接對(duì)查詢字段設(shè)置別名 SELECT username AS name,email FROM user查詢兩張表 好處:字段別名一個(gè)明顯的效果是可以自定義查詢數(shù)據(jù)返回的字段名;當(dāng)兩張表有相同的字段需要都被查詢出,使用別名可以完美的進(jìn)行區(qū)分,避免沖突
delete t1,t2 from t_a t1 , t_b t2 where t1.id = t2.id
別名使用注意事項(xiàng)
書寫sql語(yǔ)句的注意事項(xiàng)書寫規(guī)范上的注意
為了增強(qiáng)性能的注意
完 |
|
|