在一個(gè)生產(chǎn)庫上,沒有創(chuàng)建索引,是不可思議的,當(dāng)然你的索引創(chuàng)建的太多了、冗余了,更是不可思議的。恰當(dāng)?shù)乃饕軌蛱岣吣愕臄?shù)據(jù)庫性能,反之則提高維護(hù)成本,下面就介紹一款工具,來分析你的mysql庫的索引是不是有冗余,pt-duplicate-key-checker,它能從mysql表中找出重復(fù)的索引和外鍵,這個(gè)工具會(huì)將重復(fù)的索引和外鍵都列出來,并生成刪除重復(fù)索引的語句,非常方便。工具詳細(xì)介紹請(qǐng)參考
成都創(chuàng)新互聯(lián)公司致力于互聯(lián)網(wǎng)網(wǎng)站建設(shè)與網(wǎng)站營銷,提供網(wǎng)站設(shè)計(jì)制作、成都做網(wǎng)站、網(wǎng)站開發(fā)、seo優(yōu)化、網(wǎng)站排名、互聯(lián)網(wǎng)營銷、微信小程序開發(fā)、公眾號(hào)商城、等建站開發(fā),成都創(chuàng)新互聯(lián)公司網(wǎng)站建設(shè)策劃專家,為不同類型的客戶提供良好的互聯(lián)網(wǎng)應(yīng)用定制解決方案,幫助客戶在新的全球化互聯(lián)網(wǎng)環(huán)境中保持優(yōu)勢。
官文:
直接上實(shí)例:
[root@localhost?bin]#?./pt-duplicate-key-checker?-h192.168.2.88
-unigel?-p123456??-dnigel
#
########################################################################
#
nigel.a1
#
########################################################################
#?dx_cd?is?a?left-prefix?of?dx_cd_b
#?Key?definitions:
#???KEY?`dx_cd`?(`cd`)
#???KEY?`dx_cd_b`
(`cd`,`b`),
#?Column?types:
#
`cd`?varchar(50)?default?null
#
`b`?varchar(100)?default?null
#?To?remove?this?duplicate?index,?execute:
ALTER?TABLE?`nigel`.`a1`?DROP?INDEX?`dx_cd`;
#
########################################################################
#
nigel.students
#
########################################################################
#?dx_n?is?a?left-prefix?of?dx_n_s
#?Key?definitions:
#???KEY?`dx_n`?(`name`),
#???KEY?`dx_n_s`
(`name`,`score`),
#?Column?types:
#
`name`?varchar(25)?default?null
#
`score`?int(5)?unsigned?not?null
#?To?remove?this?duplicate?index,?execute:
ALTER?TABLE?`nigel`.`students`?DROP?INDEX?`dx_n`;
#
########################################################################
#?Summary?of
indexes
#
########################################################################
#?Size?Duplicate?Indexes
1348
#?Total?Duplicate?Indexes??2
#?Total
Indexes
8
[root@localhost?bin]#
索引覆蓋是指如果查詢的列恰好是索引的一部分,那么查詢只需要在索引文件上進(jìn)行,不需要回行到磁盤再找數(shù)據(jù)。這種查詢速度非???稱為”索引覆蓋”
? ? 1查詢頻繁????2區(qū)分度高????3長度小????4盡量能覆蓋常用查詢字段
索引長度直接影響索引文件的大小,影響增刪改的速度,并間接影響查詢速度(占用內(nèi)存多)。因此對(duì)于一些長短不同的字節(jié),我們會(huì)針對(duì)列中的值,從左往右截取部分,來建索引。但是:
1:截的越短, 重復(fù)度越高,區(qū)分度越小, 索引效果越不好
2:截的越長, 重復(fù)度越低,區(qū)分度越高, 索引效果越好,但帶來的影響也越大--增刪改變慢,并間影響查詢速度.
所以,我們要在 ?區(qū)分度 + 長度 ?兩者上,取得一個(gè)平衡( distinct?去重 )
? ? select count (distinct?left (word,6)) / count (*) from tablename;
對(duì)于一般的系統(tǒng)應(yīng)用區(qū)別度能達(dá)到 0.1 ,索引的性能就可以接受.
? ? alter table tablename add index word(word(4));
給字符串類型的字段建立索引效率不高,但是必須要經(jīng)常查這個(gè)字段怎么建索引?
比如說一個(gè)字段url,類型是字符串。那么可以建一個(gè)字段 crcurl 來存儲(chǔ)url字段crc32后的值,并給 crcurl 建立索引。
???crc32:循環(huán)冗余校驗(yàn)。根據(jù)網(wǎng)上數(shù)據(jù)包或計(jì)算機(jī)文件等數(shù)據(jù)產(chǎn)生簡短固定位數(shù)校驗(yàn)碼的一種散列函數(shù),主要用來檢測或校驗(yàn)數(shù)據(jù)傳輸或者保存后可能出現(xiàn)的錯(cuò)誤。生成的數(shù)字在傳輸或者存儲(chǔ)之前計(jì)算出來并且附加到數(shù)據(jù)后面,然后接收方進(jìn)行檢驗(yàn)確定數(shù)據(jù)是否發(fā)生變化。一般來說,循環(huán)冗余校驗(yàn)的值都是32位的整數(shù)。
crc32 是整形,在MySQL中,給整形字段建立索引效率比較高,crc32雖然不能確保唯一性,但是無礙,相同的機(jī)率也是極小,關(guān)鍵是可以大大減少查詢的范圍,給crcurl這個(gè)字段建立索引,查詢的時(shí)候帶上crcurl字段就可以利用到索引。
? ? ? ? 不允許翻過100頁(百度搜索一般到70頁左右)?
首先我們直接大數(shù)據(jù)分頁limit 5000000,10? 發(fā)現(xiàn)耗時(shí)4.41秒
接下來我們轉(zhuǎn)換方式使用where條件查詢,只耗時(shí)0.02秒
? ? ? ? 2次的查詢結(jié)果不一致,這是因?yàn)閿?shù)據(jù)被物理刪除過有空洞.,因此我們可以追加軟刪除功能
分析:優(yōu)化思路是 不查,少查,查索引,少取.
我們現(xiàn)在必須要查,則只查索引,不查數(shù)據(jù),得到id.
再用id去查具體條目. ?這種技巧就是延遲索引.
? ? 分析:limit是先查詢?cè)僭竭^,也就是說我們先查詢出所有數(shù)據(jù)再進(jìn)行跳躍,上圖我們?cè)竭^500W頁,還使用了inner?join? 內(nèi)存并沒有崩掉,這是因?yàn)槲覀冏泳鋞mp臨時(shí)表中只查詢了id(索引覆蓋,不需要回行去磁盤找數(shù)據(jù)了)然后拿到這10個(gè)id?分別查詢這10條數(shù)據(jù) 。
排序可能發(fā)生2種情況:
1:對(duì)于覆蓋索引,直接在索引上查詢時(shí),就是有順序的, using index
2:先取出數(shù)據(jù),形成臨時(shí)表做filesort(文件排序,但文件可能在磁盤上,也可能在內(nèi)存中)
我們的爭取目標(biāo):取出來的數(shù)據(jù)本身就是有序的! 利用索引來排序,那么什么時(shí)候發(fā)生索引排序呢?即查詢索引和order by的字段是同一個(gè)字段
???goods表中 cat_id與shop_price組成聯(lián)合索引:
select goods_id,cat_id,shop_price from goods where cat_id=4 order by shop_price;????可以直接利用索引來排序,
using where按照shop_price索引取出的結(jié)果,本身就是有序的
? ? ?????select goods_id,cat_id,shop_price from goods order by click_count;
? ? ? ? ? using filesort用到了文件排序,即取出的結(jié)果再次排序
重復(fù)索引是指 在同1個(gè)列(如age), 或者順序相同的幾個(gè)列(age,school), 建立了多個(gè)索引,稱為重復(fù)索引,重復(fù)索引沒有任何幫助,只會(huì)增大索引文件,拖慢更新速度。
冗余索引是指2個(gè)索引所覆蓋的列有重疊, 稱為冗余索引。比如x,m,列,加索引 index x(x), ?index xm(x,m) x,xm索引, 兩者的x列重疊了, ?這種情況,稱為冗余索引. (mx, xm 不是重復(fù)的,因?yàn)榱械捻樞虿灰粯樱?/p>
SHOW INDEX FROM tbl_name [FROM db_name]
例如,
mysql SHOW INDEX FROM mytable FROM mydb;
mysql SHOW INDEX FROM mydb.mytable;
SHOW KEYS是SHOW INDEX的同義詞。您也可以使用mysqlshow -k db_name tbl_name命令列舉一個(gè)表的索引。
SHOW INNODB STATUS語法
SHOW INNODB STATUS
SHOW INDEX會(huì)返回表索引信息。其格式與ODBC中的SQLStatistics調(diào)用相似。
SHOW INDEX會(huì)返回以下字段:
· Table
表的名稱。
· Non_unique
如果索引不能包括重復(fù)詞,則為0。如果可以,則為1。
· Key_name
索引的名稱。
· Seq_in_index
索引中的列序列號(hào),從1開始。
· Column_name
列名稱。
· Collation
列以什么方式存儲(chǔ)在索引中。在MySQL中,有值‘A’(升序)或NULL(無分類)。
· Cardinality
索引中唯一值的數(shù)目的估計(jì)值。通過運(yùn)行ANALYZE TABLE或myisamchk -a可以更新?;鶖?shù)根據(jù)被存儲(chǔ)為整數(shù)的統(tǒng)計(jì)數(shù)據(jù)來計(jì)數(shù),所以即使對(duì)于小型表,該值也沒有必要是精確的?;鶖?shù)越大,當(dāng)進(jìn)行聯(lián)合時(shí),MySQL使用該索引的機(jī)會(huì)就越大。
· Sub_part
如果列只是被部分地編入索引,則為被編入索引的字符的數(shù)目。如果整列被編入索引,則為NULL。
· Packed
指示關(guān)鍵字如何被壓縮。如果沒有被壓縮,則為NULL。
· Null
如果列含有NULL,則含有YES。如果沒有,則該列含有NO。
· Index_type
用過的索引方法(BTREE, FULLTEXT, HASH, RTREE)。
· Comment
多種評(píng)注。