真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

mysql讀取順序怎么看 mysql查詢的執(zhí)行順序

MySQL各部分的執(zhí)行順序

前幾天參加了一個公司的面試,到了后面面試官出了一個SQL相關(guān)的題目:

創(chuàng)新互聯(lián)建站專注于企業(yè)成都營銷網(wǎng)站建設(shè)、網(wǎng)站重做改版、長安網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、成都h5網(wǎng)站建設(shè)、商城網(wǎng)站定制開發(fā)、集團公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為長安等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。

數(shù)據(jù)的形式類似于以下這樣(表名為views):

當(dāng)時為了穩(wěn)妥起見,我的第一反應(yīng)是使用窗口函數(shù),

然后面試官問:“還有沒有什么簡便的方法么?”

很明顯他的意思是要用傳統(tǒng)的groupby來完成這個查詢,確實我之前的查詢又是用窗口函數(shù)又是加了distinct確實是復(fù)雜一些。

于是我用group by再寫了一遍。

看完我的查詢之后,面試官又問了一句:“可以不需要使用嵌套查詢嗎?”

當(dāng)時我的回答是”應(yīng)該不行,如果不使用嵌套而直接在group by后面加having的話sql會報錯,就和where如果使用別名查詢就會報錯一樣“

后面面試完想了一下,發(fā)現(xiàn)自己當(dāng)時回答得不好,不是正確的但也不完全錯,不是正確的原因是按照sql的規(guī)則having后面是可以拿聚合函數(shù)做判斷的,但是不完全錯的原因是如果having用的是像我之前設(shè)置的別名來判斷的話,確實是會出錯的。(雖然mysql在5.6之后基于sql的規(guī)則對group by進(jìn)行拓展,支持這種寫法。但在其它sql上面用別名having還是不行的)

我們可以從SQL運行時各部分的執(zhí)行順序來進(jìn)行分析,當(dāng)我們選擇執(zhí)行一個SQL語句的時候,它會按照以下的順序來進(jìn)行操作,

這個執(zhí)行順序的設(shè)計是很巧妙的,我說一下我自己對于上述順序的理解,

1. FROM

顧名思義,當(dāng)執(zhí)行查詢語句的時候,首先需要知道的是它需要哪些表,正如我們?nèi)ヒ粋€地方需要知道它的具體位置一樣。如果需要多個表的話在這一部分也需要按照一定的順序進(jìn)行表的join操作。

2. WHERE

當(dāng)確定我們需要讀取哪一張表(或者多張表)的數(shù)據(jù)之后,我們就需要進(jìn)行where的filter操作,根據(jù)filter盡量減少讀取的數(shù)據(jù)數(shù)量。

那么問題來了,為什么where的優(yōu)先級要比group by,having, select之類的要高呢?

第一個原因是可以減少不必要的查詢量,加快執(zhí)行語句的速度,類似于Apache Spark在對查詢語句進(jìn)行邏輯優(yōu)化時需要用到的謂詞下推類似的道理。舉個栗子,比如我們可能需要userid從100到300的用戶對于某一個頁面的瀏覽次數(shù),那么如果先執(zhí)行g(shù)roup by再執(zhí)行where的話,userid小于100的用戶的數(shù)據(jù)也會被匯總進(jìn)去,但實際上這些部分的數(shù)據(jù)是完全不需要的,計算它們完全是浪費系統(tǒng)資源(而且group by操作本身就是很耗資源的操作)

3. GROUP BY

在完成where操作的過濾之后,如果語句中有g(shù)roup by的話則會對過濾后的數(shù)據(jù)進(jìn)行聚合操作,聚合操作是多對一的轉(zhuǎn)換,因此在聚合操作過后,除了用于group by的字段之外,其它字段的原始數(shù)據(jù)將會丟失,只能得到它們相應(yīng)的聚合結(jié)果(比如sum(), avg()這樣)

在完成聚合操作之后,參與group by的字段以及其它字段對應(yīng)的聚合值已經(jīng)處于已知狀態(tài),后續(xù)的操作可以直接使用它們。

4. HAVING

HAVING操作主要做的是對group by之后的分組結(jié)果進(jìn)行過濾,可以根據(jù)參與group by的字段進(jìn)行過濾,也可以根據(jù)其它字段的聚合值進(jìn)行過濾。(因為聚合值在這里已經(jīng)算是已知數(shù)據(jù))因此這里是可以拿聚合函數(shù)做判斷的,比如最開始的那個查詢的例子,可以直接寫成以下的形式,

HAVING并不是一定要和group by成對出現(xiàn)的,它也可以單獨存在,在沒有g(shù)roup by的時候,此時默認(rèn)只有一個組,但是需要注意的是這時having里面參與過濾的字段需要在select里面存在,不然having會不知道這是分組里面的內(nèi)容而導(dǎo)致報錯。

5. SELECT

選取結(jié)果集中相對應(yīng)的字段,在select中為字段設(shè)置的別名在此階段及之后的操作中生效。

6. DISTINCT

去重操作,放在select之后有個原因是去重操作是要根據(jù)select里面所選字段來進(jìn)行的。

7. ORDER BY

對得到的結(jié)果按照特定字段順序進(jìn)行排列,這里可以使用別名

8. LIMIT

設(shè)置顯示結(jié)果集中的幾條數(shù)據(jù)

通過分析MySQL中各部分的執(zhí)行順序,我們就不難理解為什么where不能有別名,而having可以用聚合函數(shù)來判斷的原因,而且借此機會重新溫習(xí)一遍SQL各部分對應(yīng)的功能,加深理解,可以說是一舉兩得。

從啟動腳本分析mysql讀取my.cnf配置的順序

當(dāng)同一臺主機搭建多個mysql實例,在利用service mysql start時候,會因為讀取/etc/my.cnf導(dǎo)致啟動報錯。而網(wǎng)上說的/etc/my.cnf - /etc/mysql/my.cnf - /usr/local/mysql/etc/my.cnf - ~/.my.cnf順序并沒有鳥用,有時會花費很長時間定位,現(xiàn)從啟動腳本分析mysql的啟動原理。

一、我的環(huán)境共存在三臺3臺mysql

1)、第一臺為rpm包裝的mysql(一般系統(tǒng)會自帶mysql就是rpm安裝的),默認(rèn)安裝路徑為/usr/local,默認(rèn)的配置文件為/etc/my.cnf。

2)、其他兩臺新增mysql安裝路徑分別為:/home/mysql-5.7.21、/home/mysql-5.7.21_two,配置文件分別為:/home/mysql-5.7.21/my.cnf、/home/mysql-5.7.21_two/my.cnf

3)、啟動腳本:我的習(xí)慣是將$MYSQL_HOME/support-files/mysql.server復(fù)制到/etc/init.d/下面,并重命名,如下圖:mysql1和mysql2分別為兩臺新增mysql的啟動腳本,可利用service mysql1 start和service mysql2 start啟動(分別修改了--basedir和--datadir)。

二、以/etc/init.d/mysql1分析啟動腳本

1)、啟動腳本的核心思想是,先利用(parse_server_arguments `$print_defaults $extra_args mysqld server mysql_server mysql.server`)語句獲取配置文件中的參數(shù)。然后利用($bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args /dev/null )啟動mysql實例。

2)、問題的關(guān)鍵點就在$print_defaults $extra_args mysqld server mysql_server mysql.server

故我的獲取配置文件的參數(shù)實際是通過如下語句獲?。?/p>

但是此時存在一個問題:

腳本的執(zhí)行結(jié)果顯示,不僅讀取到了/home/mysql-5.7.21/my.cnf中的內(nèi)容,還讀取到了/etc/my.cnf中的參數(shù)。那么mysql1腳本只修改--basedir和datadir顯然不行,仍然會由于/etc/my.cnf導(dǎo)致問題。其實如果~/.my.cnf如果也存在的話,~/.my.cnf中的參數(shù)也會被讀取出。

這時候就需要用到"--defaults-file"參數(shù)

再回到$extra_args參數(shù)的獲取腳本,會發(fā)現(xiàn)只要$basedir/my.cnf存在就會被同時讀取,而我們的目的是只讀取這個配置文件。

所以:我們可以修改下這個腳本,將extra_args的值變?yōu)?--defaults-file =$basedir/my.cnf,這樣煤氣啟動就只讀取這個配置文件,如果$basedir/my.cnf不存在或沒有可讀權(quán)限,直接提示報錯。

三、$bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args /dev/null 啟動時

1)、新的問題:

我的$basedir/my.cnf中明明沒有ndb-connectstring=172.16.31.111參數(shù),怎么會提示這個變量無法識別呢?

查看/etc/my.cnf發(fā)現(xiàn)這個參數(shù)確實存在,funk?。?!但上面明明只讀取$basedir/my.cnf中配置文件了??!

2)、查看mysqld_safe的使用方法

也就是,需要在利用mysqld_safe啟動時候再指定下配置,讓其只讀取$basedir/my.cnf。故在啟動行加入--defaults-file="$basedir/my.cnf"

總結(jié):在將mysql.server復(fù)制到/etc/init.d后,有刪除需要配置修改,到此為止新增的mysql已經(jīng)能夠讀取指定配置文件啟動

遺留問題:

為什么讀取指定配置文件后,$bindir/mysqld_safe還是讀取/etc/my.cnf?故,還需對mysqld_safe做出debug分析,待補充,歡迎到時查看!

如何查看MySQL配置文件的讀取順序

ocate my.cnf; 看看你的linux上有多少個my.cnf,一般都配置為/etc/my.cnf 然后再用show variables,看看 strace -e stat64 mysqld --print-defaults 這樣子也行


當(dāng)前名稱:mysql讀取順序怎么看 mysql查詢的執(zhí)行順序
新聞來源:http://weahome.cn/article/hjehdd.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部