本篇內(nèi)容主要講解“如何理解MySQL索引cardinalit”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“如何理解MySQL索引cardinalit”吧!
創(chuàng)新互聯(lián)堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計制作、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的河?xùn)|網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
查看一個表的索引:
mysql> show index from rank_item; +-----------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | +-----------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | rank_item | 0 | PRIMARY | 1 | id | A | 5665508 | NULL | NULL | | BTREE | | | | rank_item | 1 | idx_city_category | 1 | city | A | 2713 | NULL | NULL | | BTREE | | | | rank_item | 1 | idx_city_category | 2 | category | A | 3798 | NULL | NULL | YES | BTREE | | | | rank_item | 1 | idx_artisan_id | 1 | artisan_id | A | 33916 | NULL | NULL | YES | BTREE | | | | rank_item | 1 | index_weight | 1 | weight | A | 11680 | NULL | NULL | YES | BTREE | | | | rank_item | 1 | product_id_plan_id | 1 | product_id | A | 1480432 | NULL | NULL | | BTREE | | | | rank_item | 1 | product_id_plan_id | 2 | plan_id | A | 5590288 | NULL | NULL | YES | BTREE | | | | rank_item | 1 | idx_cat_ci_art | 1 | category | A | 3170 | NULL | NULL | YES | BTREE | | | | rank_item | 1 | idx_cat_ci_art | 2 | city | A | 11417 | NULL | NULL | | BTREE | | | | rank_item | 1 | idx_cat_ci_art | 3 | artisan_id | A | 46514 | NULL | NULL | YES | BTREE | | | | rank_item | 1 | idx_ca_ci_pid_wei | 1 | category | A | 3187 | NULL | NULL | YES | BTREE | | | | rank_item | 1 | idx_ca_ci_pid_wei | 2 | city | A | 10869 | NULL | NULL | | BTREE | | | | rank_item | 1 | idx_ca_ci_pid_wei | 3 | plan_id | A | 17403 | NULL | NULL | YES | BTREE | | | | rank_item | 1 | idx_ca_ci_pid_wei | 4 | weight | A | 659306 | NULL | NULL | YES | BTREE | | | +-----------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
上面有一個屬性Cardinality,可以通過觀察它來評估索引是否合理。它會估計索引中不重復(fù)記錄,如果這個相對值很小,可能就要評估索引是否有意義。
查看表的總行數(shù):
mysql> select count(*) as total from rank_item; +---------+ | total | +---------+ | 5581872 | +---------+
觀察以下信息:
id列:Cardinality/total=5608506/5581872=1.005
city列:Cardinality/total=2713/5581872=0.0000486
category列:Cardinality/total=3170/5581872=0.0000568
列id由于是主鍵,通過cardinality估算出來的值/總數(shù)接近于1;而另外2個索引列,估算出來的值/總數(shù)都趨近于0。估算出來的值/總數(shù)=占比,我們稱占比為相對值。
通過上面表格做一個大膽推測,查詢id列是很快,查詢另外2列是很慢;現(xiàn)在我們看下相應(yīng)的執(zhí)行計劃。
mysql> explain select * from rank_item where id=2419; +----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ | 1 | SIMPLE | rank_item | NULL | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | NULL | +----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ 1 row in set, 1 warning (0.00 sec) mysql> explain select * from rank_item where city=4967; +----+-------------+-----------+------------+------+-------------------+-------------------+---------+-------+--------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------+------------+------+-------------------+-------------------+---------+-------+--------+----------+-------+ | 1 | SIMPLE | rank_item | NULL | ref | idx_city_category | idx_city_category | 4 | const | 556680 | 100.00 | NULL | +----+-------------+-----------+------------+------+-------------------+-------------------+---------+-------+--------+----------+-------+ 1 row in set, 1 warning (0.04 sec)
但是發(fā)現(xiàn)都會走索引,而且ref都是const。難道是cardinality不準(zhǔn)?是的,因為它是一個預(yù)估值!
上面提到cardinality是索引中不重復(fù)記錄的預(yù)估值,那么它是怎么實現(xiàn)的呢?由于Mysql的B+索引在每個存儲引擎中實現(xiàn)的都不一樣,所以cardinality干脆放到存儲引擎層面實現(xiàn)的!
對于innodb來說,達到以下2點就會重新計算cardinality
如果表中1/16的數(shù)據(jù)發(fā)生變化
如果stat_modified_counter>200 000 0000
這是為什么呢?因為真實環(huán)境中,索引的更新可能非常頻繁,比如一個表中數(shù)據(jù)的插入,更新,刪除等,每次都去統(tǒng)計cardinality會帶來很大的負(fù)擔(dān);另外如果是一個大表,統(tǒng)計一次可能非常耗時?;诖?,采用基于上面2個條件的"抽樣"統(tǒng)計的方式。
那上面2種有什么區(qū)別呢?
如果表中1/16數(shù)據(jù)發(fā)生變化則會更新;第2種情況比較特別,如果某一千數(shù)據(jù)頻繁更新,但是數(shù)據(jù)并沒有增加,則第一種無法適用,所以設(shè)置stat_modified_counter為發(fā)生變化的次數(shù);如果次數(shù)達到200 000 0000,也會更新統(tǒng)計值。
那具體是如何采樣統(tǒng)計的呢?
獲取B+樹葉子節(jié)點的數(shù)據(jù),記為A
隨機獲得B+樹索引中8個葉子節(jié)點。統(tǒng)計每個頁不同記錄的個數(shù),分別記為P1,P2...P8
計算cardinality = (P1+P2+...P8)A/8
從而得出索引中不同記錄的數(shù)量。從上面可以發(fā)現(xiàn),有2個問題
1、由于是隨機采樣的方式,所以會出現(xiàn),連續(xù)2次統(tǒng)計,數(shù)量都不同。只有在表數(shù)據(jù)非常少,葉子節(jié)點不多于8個時,每次采樣都是取到相同的頁,統(tǒng)計值才會相同。
2、由于統(tǒng)計值是基于上面2個條件去更新的,可能出現(xiàn)系統(tǒng)運行了一段時間之后,數(shù)據(jù)發(fā)生了很大變化,統(tǒng)計值偏差比較大了,那么索引的效率會下降。
那對于問題2,該怎么處理呢?
如果系統(tǒng)運行一段時間之后,我們可以通過執(zhí)行下面的sql,重新計算cardinality值。
analyze table tablename;
不過,如果表很大,重新統(tǒng)計可能會非常耗時間,建議對于核心表,在非高峰時段操作
現(xiàn)在又回到前面的例子,我們通過觀察執(zhí)行計劃發(fā)現(xiàn),不論cardinality大小,相對值大小,發(fā)現(xiàn)還是會走索引,那為什么要說對于相對值非常小的不建議建索引呢?這就涉及到一個選擇性的問題
比如有一個用戶表,有一列性別sex,現(xiàn)在要查詢所以性別為male的用戶(假定只有男人-male,女人-female,沒有其它不明性別),可能的sql:
select * from user where sex = 'M';
對于這個sql,雖然sex上有索引,但是執(zhí)行的時候,讀取的數(shù)據(jù)可能會超過一半,甚至在極端情況下(比如程序員的網(wǎng)站),大部分?jǐn)?shù)據(jù)都需要讀取,所以還是會走全表掃描,這種數(shù)據(jù)稱為低選擇性。反之,如果是高選擇性的,建議建索引 ,比如user表中用戶,一般來說很少重復(fù);
到此,相信大家對“如何理解MySQL索引cardinalit”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
分享文章:如何理解MySQL索引cardinalit
文章路徑:http://muchs.cn/article22/ijoccc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管、網(wǎng)站收錄、搜索引擎優(yōu)化、微信公眾號、全網(wǎng)營銷推廣、移動網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)