一種在有序數組中查找某一特定元素的搜索算法;
二分查找法的優勢是比較少次數,查找速度快,平均性能好;其缺點是要求待查表爲有序表,且插入刪除困難,所以二分查找方法適用於不常常變更而查找頻繁的有序列表.node
innodb 要求彙集索引列都要求是有序自增列.innnodb 是事務型的存儲引擎,其中的行老是會被刪除並提交,count(*) 相對要慢一些.mysql
二叉樹的每一個節點至多隻有二棵子樹(不存在大於2的節點),二叉樹的子樹有左右有序之分,次序不能顛倒.左子樹必定小於根,右子樹必定大於根.根節點是子節點的中間節點.算法
4 1 10
數據庫裏使用平衡二叉樹,若是有插入值很大可能會致使其自旋?.
sql
有k個子節點的非葉子節點剛好包含有k-1個鍵值(索引節點)數據庫
記錄中應該用'節點'仍是'結節',baidu了一下,有師兄解釋:一個節點是兩線相交,中間的點,另外一個結點是最後的點。二叉樹好像特別一點,是結點,葉子結點和非葉子節點(但不肯定正確性,我就全部都用節點了)數組
在MySQL中,爲了方便,直接寫成BTREEbash
高度 |
---|
1 |
2 |
3 |
4 |
sql root@localhost [sysbench_testdata]>show create table sbtest2; | sbtest2 | CREATE TABLE
sbtest2(
idint(11) NOT NULL AUTO_INCREMENT,
kint(11) NOT NULL DEFAULT '0',
cchar(120) NOT NULL DEFAULT '',
padchar(60) NOT NULL DEFAULT '', PRIMARY KEY (
id), KEY
k_2(
k`)root@localhost [sysbench_testdata]>select count(id) from sbtest2;
+-----------+
| count(id) |
+-----------+
| 67840914 |
+-----------+
1 row in set (56.87 sec)數據結構
```性能
root@localhost [sysbench_testdata]>SELECT b.name, a.name, index_id, type, a.space, a.PAGE_NO FROM information_schema.INNODB_SYS_INDEXES a, information_schema.INNODB_SYS_TABLES b WHERE a.table_id = b.table_id AND a.space <> 0 and b.name='sysbench_testdata/sbtest2'; +---------------------------+---------+----------+------+-------+---------+ | name | name | index_id | type | space | PAGE_NO | +---------------------------+---------+----------+------+-------+---------+ | sysbench_testdata/sbtest2 | PRIMARY | 51 | 3 | 33 | 3 | | sysbench_testdata/sbtest2 | k_2 | 58 | 0 | 33 | 38 | +---------------------------+---------+----------+------+-------+---------+ 2 rows in set (0.00 sec) root@localhost [sysbench_testdata]>show global variables like 'innodb_page_size'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | innodb_page_size | 16384 | +------------------+-------+ 1 row in set (0.00 sec)
#hexdump -s 49216 -n 10 ./sbtest2.ibd 000c040 0300 0000 0000 0000 3300 000c04a #hexdump -s 622656 -n 10 ./sbtest2.ibd 0098040 0200 0000 0000 0000 3a00 009804a
精確查找
有用.哈希衝突
),如在索引表裏沒法作到一一對應到記錄行?Innodb內部的自適應哈希索引和此處說的不是一回事.自適應哈希索引是沒辦法被引用和修改的,innodb自適應哈希索引只能用啓用或禁用,沒辦法指定某一個表使用哈希索引.
至關於書目,用於快速檢索mysql索引
數據變動時,索引也須要更新,下降更新效率.(更新索引時會致使cpu在sys增高),在5.7以上,能夠經過查詢獲得索引的利用率.
root@localhost [sysbench_testdata]>show status like '%Handler_read%'; +-----------------------+---------+ | Variable_name | Value | +-----------------------+---------+ | Handler_read_first | 7 | | Handler_read_key | 29 | | Handler_read_last | 0 | | Handler_read_next | 8446377 | | Handler_read_prev | 0 | | Handler_read_rnd | 20 | | Handler_read_rnd_next | 8344612 | +-----------------------+---------+ 7 rows in set (0.00 sec)
Handler_read_key這個值表明了一個行將索引值讀的次數,很低的值代表增長索引獲得的性能改善不高,由於索引並不常用。
Handler_read_rnd_next 的值高則查詢低效,而且應該創建索引補救。這個值是指在數據文件中讀下一行的請求數。若是正進行大量的表掃描,Handler_read_rnd_next的值較高,則一般說明表索引不正確或查詢沒有利用索引
2.查看具體某一個sql的索引使用狀況 :
root@localhost [sysbench_testdata]>explain select k from sbtest2 where k=432 limit 2; +----+-------------+---------+------------+------+---------------+------+---------+-------+--------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+---------+------------+------+---------------+------+---------+-------+--------+----------+-------------+ | 1 | SIMPLE | sbtest2 | NULL | ref | k_2 | k_2 | 4 | const | 110944 | 100.00 | Using index | +----+-------------+---------+------------+------+---------------+------+---------+-------+--------+----------+-------------+ 1 row in set, 1 warning (0.00 sec)
字段說明:
Type:告訴咱們對錶所使用的訪問方式,主要包含以下集中類型;
◇ all:全表掃描
◇ const:讀常量,且最多隻會有一條記錄匹配,因爲是常量,因此實際上只須要讀一次;
◇ eq_ref:最多隻會有一條匹配結果,通常是經過主鍵或者惟一鍵索引來訪問;
◇ fulltext:
◇ index:全索引掃描;
◇ index_merge:查詢中同時使用兩個(或更多)索引,而後對索引結果進行merge 以後再讀取表數據;
◇ index_subquery:子查詢中的返回結果字段組合是一個索引(或索引組合),但不是一個主鍵或者惟一索引;
◇ rang:索引範圍掃描;
◇ ref:Join 語句中被驅動表索引引用查詢;
◇ ref_or_null:與ref 的惟一區別就是在使用索引引用查詢以外再增長一個空值的查詢;
◇ system:系統表,表中只有一行數據;
◇ unique_subquery:子查詢中的返回結果字段組合是主鍵或者惟一約束;
possible_keys:可能能夠利用的索引的名字。這裏的索引名字是建立索引時指定的索引暱稱;若是索引沒有暱稱,則默認顯示的是索引中第一個列的名字(在本例中,它是「firstname」)。默認索引名字的含義每每不是很明顯。
key:它顯示了MySQL實際使用的索引的名字。若是它爲空(或NULL),則MySQL不使用索引。
key_len:索引中被使用部分的長度,以字節計
ref:列出是經過常量(const),仍是某個表的某個字段(若是是join)來過濾(經過key)
的;
rows:MySQL所認爲的它在找到正確的結果以前必須掃描的記錄數。顯然,這裏最理想的數字就是1。
root@localhost [sysbench_testdata]>select object_type,object_schema,object_name,index_name,count_star,count_read,COUNT_FETCH from performance_schema.table_io_waits_summary_by_index_usage where object_name='sbtest2';
root@localhost [sysbench_testdata]>select object_type,object_schema,object_name,index_name,count_star,count_read,COUNT_FETCH from performance_schema.table_io_waits_summary_by_index_usage where object_name='sbtest2'; ERROR 2006 (HY000): MySQL server has gone away No connection. Trying to reconnect... Connection id: 1697669 Current database: sysbench_testdata +-------------+-------------------+-------------+------------+------------+------------+-------------+ | object_type | object_schema | object_name | index_name | count_star | count_read | COUNT_FETCH | +-------------+-------------------+-------------+------------+------------+------------+-------------+ | TABLE | sysbench_testdata | sbtest2 | PRIMARY | 0 | 0 | 0 | | TABLE | sysbench_testdata | sbtest2 | k_2 | 76287298 | 76287298 | 76287298 | | TABLE | sysbench_testdata | sbtest2 | NULL | 8344631 | 8344631 | 8344631 | +-------------+-------------------+-------------+------------+------------+------------+-------------+ 3 rows in set (0.00 sec) root@localhost [sysbench_testdata]>select k from sbtest2 where k=432 limit 2; +-----+ | k | +-----+ | 432 | | 432 | +-----+ 2 rows in set (0.00 sec) root@localhost [sysbench_testdata]>select object_type,object_schema,object_name,index_name,count_star,count_read,COUNT_FETCH from performance_schema.table_io_waits_summary_by_index_usage where object_name='sbtest2'; +-------------+-------------------+-------------+------------+------------+------------+-------------+ | object_type | object_schema | object_name | index_name | count_star | count_read | COUNT_FETCH | +-------------+-------------------+-------------+------------+------------+------------+-------------+ | TABLE | sysbench_testdata | sbtest2 | PRIMARY | 0 | 0 | 0 | | TABLE | sysbench_testdata | sbtest2 | k_2 | 76287300 | 76287300 | 76287300 | | TABLE | sysbench_testdata | sbtest2 | NULL | 8344631 | 8344631 | 8344631 | +-------------+-------------------+-------------+------------+------------+------------+-------------+ 3 rows in set (0.01 sec) root@localhost [sysbench_testdata]>select k from sbtest2 where id=432 limit 2; +-------+ | k | +-------+ | 49866 | +-------+ 1 row in set (0.00 sec) root@localhost [sysbench_testdata]>select object_type,object_schema,object_name,index_name,count_star,count_read,COUNT_FETCH from performance_schema.table_io_waits_summary_by_index_usage where object_name='sbtest2'; +-------------+-------------------+-------------+------------+------------+------------+-------------+ | object_type | object_schema | object_name | index_name | count_star | count_read | COUNT_FETCH | +-------------+-------------------+-------------+------------+------------+------------+-------------+ | TABLE | sysbench_testdata | sbtest2 | PRIMARY | 1 | 1 | 1 | | TABLE | sysbench_testdata | sbtest2 | k_2 | 76287300 | 76287300 | 76287300 | | TABLE | sysbench_testdata | sbtest2 | NULL | 8344631 | 8344631 | 8344631 | +-------------+-------------------+-------------+------------+------------+------------+-------------+ 3 rows in set (0.00 sec) root@localhost [sysbench_testdata]>
在彙集索引下,數據在物理上按順序排在數據頁上,重複值也排在一塊兒,於是在那些包含範圍檢查(between、<、<=、>、>=)或使用group by或orderby的查詢時,一旦找到具備範圍中第一個鍵值的行,具備後續索引值的行保證物理上毗連在一塊兒而沒必要進一步搜索,避免了大範圍掃描,能夠大大提升查詢速度
)mysql一個表只支持一個彙集索引。在innodb裏面彙集索引就是整個表,表就是彙集索引,由於innodb的彙集索引後面是整行數據,若是主鍵由多列組成,btree優先按第一列順序存儲,在彙集索引btree裏面每一個葉子節點最終存儲每行數據,這就是爲何在innodb裏面沒有任何條件count (*),它會優先選擇普通索引來完成掃描,而不是採用主鍵索引,由於若是掃彙集索引,掃描的數據量更大,產生的IO更大,若是掃描普通輔助索引,那麼它的數據結構一般來說比主鍵索引小。
)mysql 彙集索引的選擇順序:若是有主鍵則選擇主鍵,沒有主鍵則選擇第一個not nullable的惟一索引,沒有知足要求的惟一鍵,最後會使用rowid.,但這個rowid爲實例級全局id,因此若是彙集索引若是選擇rowid,可能會致使性能下降
MySQL 5.6.9及之後無論索引定義時,有無顯示包含主鍵,實際都會存儲主鍵值,如:c1爲主鍵,索引z,爲c2,c3聯合索引,但z會存儲c1的值,這一特性加:索引擴展(Index Extensions).
-查詢中是基於主鍵好,仍是惟一索引好?
惟一索引約束可臨時禁用,但主鍵不行;
須要的數據都在索引覆蓋的字段範圍內,不須要再去表中取數據
,若是使用的覆蓋索引,執行計劃中的Extra列會顯示關鍵字:using index)建議:
1.where條件中,常常同時出現的列放在聯合索引中;2把選擇性(過濾性/基數)大的列放在聯合索引的最左邊(常常出現的列放在最左邊
).
執行計劃中的Extra列會顯示關鍵字:using index.