日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

用MySql的查询分析语法explain来优化查询和索引

發(fā)布時(shí)間:2024/4/17 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用MySql的查询分析语法explain来优化查询和索引 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

http://hi.baidu.com/wtnzone/item/beb83840a4971af4dd0f6c77

 數(shù)據(jù)庫(kù)最常見(jiàn)的操作就是查詢了,我們經(jīng)常要用"SELECT"語(yǔ)法對(duì)已有的表進(jìn)行某種檢索,但是在實(shí)際應(yīng)用中,查詢前我們并不知道該查詢會(huì)如何運(yùn)行、會(huì)使用多少時(shí)間、會(huì)涉及多少字段和記錄,每次輸入了SQL語(yǔ)句,點(diǎn)擊運(yùn)行,然后慢慢等待結(jié)果的出現(xiàn),好的查詢語(yǔ)句效率很高,而有時(shí)候也會(huì)遇到查詢緩慢,久久沒(méi)有運(yùn)行完成的情況。

  由于我們并不知道實(shí)際查詢的時(shí)候數(shù)據(jù)庫(kù)里發(fā)生了什么,數(shù)據(jù)庫(kù)軟件是怎樣掃描表、怎樣使用索引,因此我們能感知的就只有查詢運(yùn)行的時(shí)間,而往往在數(shù)據(jù)規(guī)模不大時(shí),查詢是瞬間的,因此在寫(xiě)SQL語(yǔ)句時(shí)也就比較隨意,也很少使用索引來(lái)加速查詢的速度。不過(guò)一旦數(shù)據(jù)規(guī)模增大,比如百萬(wàn)、千萬(wàn)、幾億的時(shí)候,我們寫(xiě)同樣的查詢語(yǔ)句卻發(fā)現(xiàn)窗口遲遲沒(méi)有結(jié)果,這個(gè)時(shí)候才知道數(shù)據(jù)規(guī)模已經(jīng)限制了我們自由查詢的速度。查詢優(yōu)化和索引也就顯得很重要了。

  那么,能不能在查詢前就能預(yù)先估計(jì)查詢究竟要涉及多少行、使用哪些索引、運(yùn)行多久呢?答案是可以的,MySql和SQL Server都提供了相應(yīng)的功能和語(yǔ)法來(lái)實(shí)現(xiàn),下面用一個(gè)擁有兩千多萬(wàn)條記錄的表來(lái)說(shuō)明如何進(jìn)行查詢分析。該表有一個(gè)訪問(wèn)時(shí)間字段。

  MySql提供了EXPLAIN語(yǔ)法用來(lái)進(jìn)行查詢分析,在SQL語(yǔ)句前加一個(gè)"EXPLAIN"即可。比如我們要分析如下SQL語(yǔ)句,該語(yǔ)句獲取特定時(shí)間段的訪問(wèn)記錄總數(shù)。

EXPLAIN
SELECT COUNT(*) FROM ××××××
WHERE
TIME_INT>=UNIX_TIMESTAMP('2010-03-01 18:00:00') AND?
TIME_INT<UNIX_TIMESTAMP('2010-03-01 18:15:00')

返回的結(jié)果如下

從分析結(jié)果可知,該查詢涉及3674行,用到了timeindex這個(gè)索引,using index說(shuō)明該查詢只需要檢索索引即可完成。EXPLAIN中每一項(xiàng)的具體描述和表達(dá)的意義如下:(來(lái)自http://www.phpweblog.net/richard-dong/archive/2008/12/15/6173.aspx)

------------------------------

table | type | possible_keys | key | key_len | ref | rows | Extra

EXPLAIN列的解釋

table?
顯示這一行的數(shù)據(jù)是關(guān)于哪張表的

type?
這是重要的列,顯示連接使用了何種類型。從最好到最差的連接類型為const、eq_reg、ref、range、indexhe和ALL(后面有詳細(xì)說(shuō)明)

possible_keys?
顯示可能應(yīng)用在這張表中的索引。如果為空,沒(méi)有可能的索引。可以為相關(guān)的域從WHERE語(yǔ)句中選擇一個(gè)合適的語(yǔ)句

key?
實(shí)際使用的索引。如果為NULL,則沒(méi)有使用索引。很少的情況下,MYSQL會(huì)選擇優(yōu)化不足的索引。這種情況下,可以在SELECT語(yǔ)句中使用USE INDEX(indexname)來(lái)強(qiáng)制使用一個(gè)索引或者用IGNORE INDEX(indexname)來(lái)強(qiáng)制MYSQL忽略索引

key_len?
使用的索引的長(zhǎng)度。在不損失精確性的情況下,長(zhǎng)度越短越好

ref?
顯示索引的哪一列被使用了,如果可能的話,是一個(gè)常數(shù)

rows?
MYSQL認(rèn)為必須檢查的用來(lái)返回請(qǐng)求數(shù)據(jù)的行數(shù)

Extra?
關(guān)于MYSQL如何解析查詢的額外信息。將在表4.3中討論,但這里可以看到的壞的例子是Using temporary和Using filesort,意思MYSQL根本不能使用索引,結(jié)果是檢索會(huì)很慢

extra列返回的描述的意義

  Distinct?
一旦MYSQL找到了與行相聯(lián)合匹配的行,就不再搜索了

  Not exists?
MYSQL優(yōu)化了LEFT JOIN,一旦它找到了匹配LEFT JOIN標(biāo)準(zhǔn)的行,就不再搜索了

  Range checked for each

  Record(index map:#)?
沒(méi)有找到理想的索引,因此對(duì)于從前面表中來(lái)的每一個(gè)行組合,MYSQL檢查使用哪個(gè)索引,并用它來(lái)從表中返回行。這是使用索引的最慢的連接之一

  Using filesort?
看到這個(gè)的時(shí)候,查詢就需要優(yōu)化了。MYSQL需要進(jìn)行額外的步驟來(lái)發(fā)現(xiàn)如何對(duì)返回的行排序。它根據(jù)連接類型以及存儲(chǔ)排序鍵值和匹配條件的全部行的行指針來(lái)排序全部行

  Using index?
列數(shù)據(jù)是從僅僅使用了索引中的信息而沒(méi)有讀取實(shí)際的行動(dòng)的表返回的,這發(fā)生在對(duì)表的全部的請(qǐng)求列都是同一個(gè)索引的部分的時(shí)候

  Using temporary?
看到這個(gè)的時(shí)候,查詢需要優(yōu)化了。這里,MYSQL需要?jiǎng)?chuàng)建一個(gè)臨時(shí)表來(lái)存儲(chǔ)結(jié)果,這通常發(fā)生在對(duì)不同的列集進(jìn)行ORDER BY上,而不是GROUP BY上

  Where used?
使用了WHERE從句來(lái)限制哪些行將與下一張表匹配或者是返回給用戶。如果不想返回表中的全部行,并且連接類型ALL或index,這就會(huì)發(fā)生,或者是查詢有問(wèn)題

不同連接類型的解釋(按照效率高低的順序排序)

  system?
表只有一行:system表。這是const連接類型的特殊情況

  const?
表中的一個(gè)記錄的最大值能夠匹配這個(gè)查詢(索引可以是主鍵或惟一索引)。因?yàn)橹挥幸恍?#xff0c;這個(gè)值實(shí)際就是常數(shù),因?yàn)镸YSQL先讀這個(gè)值然后把它當(dāng)做常數(shù)來(lái)對(duì)待

  eq_ref?
在連接中,MYSQL在查詢時(shí),從前面的表中,對(duì)每一個(gè)記錄的聯(lián)合都從表中讀取一個(gè)記錄,它在查詢使用了索引為主鍵或惟一鍵的全部時(shí)使用

  ref?
這個(gè)連接類型只有在查詢使用了不是惟一或主鍵的鍵或者是這些類型的部分(比如,利用最左邊前綴)時(shí)發(fā)生。對(duì)于之前的表的每一個(gè)行聯(lián)合,全部記錄都將從表中讀出。這個(gè)類型嚴(yán)重依賴于根據(jù)索引匹配的記錄多少—越少越好

  range?
這個(gè)連接類型使用索引返回一個(gè)范圍中的行,比如使用>或<查找東西時(shí)發(fā)生的情況

  index?
這個(gè)連接類型對(duì)前面的表中的每一個(gè)記錄聯(lián)合進(jìn)行完全掃描(比ALL更好,因?yàn)樗饕话阈∮诒頂?shù)據(jù))

  ALL?
這個(gè)連接類型對(duì)于前面的每一個(gè)記錄聯(lián)合進(jìn)行完全掃描,這一般比較糟糕,應(yīng)該盡量避免

------------------------------

  弄明白了explain語(yǔ)法返回的每一項(xiàng)結(jié)果,我們就能知道查詢大致的運(yùn)行時(shí)間了,如果查詢里沒(méi)有用到索引、或者需要掃描的行過(guò)多(比如>=幾十萬(wàn)行),那么可以感到明顯的延遲。因此需要改變查詢方式或者新建索引。

  比如沒(méi)有建索引,或者查詢寫(xiě)得不好(沒(méi)有用到索引列),會(huì)造成如下掃描所有兩千多萬(wàn)條記錄的查詢方案(type為"ALL",rows有兩千多萬(wàn)),這顯然是不可取的,運(yùn)行的話至少需要一分鐘的時(shí)間。

  而一旦使用了索引,情況會(huì)大大改變,如下

  這個(gè)時(shí)候最多掃描2624條記錄,使用了索引timeindex,同時(shí)extra里有Using index,表明了列數(shù)據(jù)是從僅僅使用了索引中的信息而沒(méi)有讀取實(shí)際的行動(dòng)的表返回的,查詢速度也成千上萬(wàn)倍的提升,不到0.1秒。

  因此MySql中的explain語(yǔ)法可以幫助我們改寫(xiě)查詢,優(yōu)化表的結(jié)構(gòu)和索引的設(shè)置,從而最大地提高查詢效率。當(dāng)然,在大規(guī)模數(shù)據(jù)量時(shí),索引的建立和維護(hù)的代價(jià)也是很高的,往往需要較長(zhǎng)的時(shí)間和較大的空間,如果在不同的列組合上建立索引,空間的開(kāi)銷會(huì)更大。因此索引最好設(shè)置在需要經(jīng)常查詢的字段中。

------------------------------

  不僅是MySql,每個(gè)主流數(shù)據(jù)庫(kù)都有相應(yīng)的查詢分析的功能,比如SQL Server具有強(qiáng)大的圖形化分析功能,暫時(shí)還沒(méi)有深入研究,所以就放幾張圖吧。它不僅能仔細(xì)分析出查詢的細(xì)節(jié),連CPU使用、IO消耗等等都能進(jìn)行估計(jì)




=======http://my.oschina.net/phpnew/blog/151194

優(yōu)秀的sqlyog, 我深深地感到不安及自責(zé), 盜版用戶多年, 多少有點(diǎn)感覺(jué)過(guò)意不去, 希望富二代們能夠支持正版吧.


最近osc還在討論什么是php大牛, 以前看過(guò)帖子, 說(shuō)得非常貼切. phper, 半個(gè)運(yùn)維工程師, 半個(gè)dba, 半個(gè)前端設(shè)計(jì), 半個(gè)js動(dòng)畫(huà), 半個(gè)市場(chǎng)營(yíng)銷. 如果你的公司想發(fā)展, 請(qǐng)招一個(gè)phper, 全能型人才哪里找, 山東可以找藍(lán)翔, osc找phper.

回正題, 作為phper,當(dāng)然在dba方面也要熟悉, 本人基礎(chǔ)知識(shí)薄弱, 才疏學(xué)淺, 對(duì)sqlyog研究未盡深刻, 有錯(cuò)誤的地方請(qǐng)指點(diǎn).

Sqlyog 盜版機(jī)制做得還是不錯(cuò)的, 官網(wǎng)都不提供旗艦版下載, 可"優(yōu)秀"的中國(guó)人更為強(qiáng)大, 這不v11.13都已經(jīng)完美兼容. 有需要的同學(xué)上這兒下載:?http://www.fenanr.com/read/112140.html

簡(jiǎn)單的寫(xiě)一句查詢語(yǔ)句, 然后點(diǎn)擊左上角那個(gè)執(zhí)行, 或者按F12, 結(jié)果頁(yè)將會(huì)顯示出數(shù)據(jù). 如果你使用過(guò)舊版, 發(fā)現(xiàn)數(shù)據(jù)顯示后, 是可以編輯的. 而新版本拋棄了這個(gè)默認(rèn)設(shè)置, 我個(gè)人覺(jué)得是非常合理的.我們先是想看看, 再?zèng)Q定是否修改.sqlyog這點(diǎn)人性化考慮非常細(xì)膩.

作為優(yōu)秀的編輯器, 總是需要思考用戶所想, 有時(shí)我們?cè)诰帉?xiě)sql時(shí), 是不是想它提示出字段名呢? sqlyog在這方面做得非常強(qiáng)大. 可以提示字段名, 函數(shù), 關(guān)鍵字,元素, 數(shù)據(jù)表,
我大概歸類了一下: f: 函數(shù).? c: 字段名. k:關(guān)鍵字.? 余下一種就是數(shù)據(jù)表. 這對(duì)于許多sql編寫(xiě)者來(lái)說(shuō), 是非常方便的功能.

性能優(yōu)化才是互聯(lián)網(wǎng)技術(shù)人員的關(guān)鍵, 優(yōu)化得力可以讓速度翻倍, 那我們?cè)趺粗酪粭lsql性能如何呢? sqlyog可以快速為語(yǔ)句檢測(cè)一次解釋. 也就是explain的語(yǔ)法.?

執(zhí)行后配置文件頁(yè)將顯示出結(jié)果. 具體怎么看這表, soso吧.



在phpmyadmin中, 我們碰到個(gè)問(wèn)題就是, 我希望可以一次性寫(xiě)多條語(yǔ)句, 可以分開(kāi)執(zhí)行. 而不需要清空編輯器. sqlyog就非常智能的解決了這個(gè)問(wèn)題. 你可以在編輯器中寫(xiě)無(wú)數(shù)條sql, 只要記得結(jié)束加分號(hào).
鼠標(biāo)光標(biāo)所在的那一條, 將會(huì)被執(zhí)行. 也就是你點(diǎn)到哪, 就執(zhí)行哪一句. 這樣你就可以一條語(yǔ)句延伸N條test語(yǔ)句, 直觀地運(yùn)行查看性能結(jié)果.?


無(wú)論多少條語(yǔ)句, 編寫(xiě)的智能提示仍然有效.

常用的四條語(yǔ)句, 有時(shí)要完全寫(xiě)出來(lái), 還真不是件容易的事, 而在sqlyog中就容易了, 直接界面操作, 或者按快捷鍵.

?系統(tǒng)默認(rèn)釋放的sql, 可能跟你想像中的不太一樣, 或許不夠直觀, 特別在過(guò)程,聯(lián)表, 觸發(fā)器語(yǔ)句中, 格式化查詢后的效果會(huì)非常明顯.

當(dāng)在創(chuàng)建臨時(shí)表語(yǔ)句中, 會(huì)碰到許多里里外外的分號(hào), 也就把sql給分隔了, 導(dǎo)致執(zhí)行失敗. sqlyog當(dāng)然不會(huì)犯這種低級(jí)錯(cuò)誤, 而是需要把語(yǔ)句選擇起來(lái)執(zhí)行, 如圖片所示.
圖片中演示的是一次性將兩條語(yǔ)句執(zhí)行起來(lái). 下面會(huì)出現(xiàn)二個(gè)結(jié)果頁(yè). 分別代表每語(yǔ)句的結(jié)果. 這功能相信你不會(huì)錯(cuò)過(guò).

我想,sqlyog 更為強(qiáng)大的是歷史記錄功能, 非常明了的列表, 執(zhí)行時(shí)間, 執(zhí)行效率.


總結(jié)

以上是生活随笔為你收集整理的用MySql的查询分析语法explain来优化查询和索引的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。