一种在有序数组中查找某一特定元素的搜索算法;
二分查找法的优势是比较少次数,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难,所以二分查找方法适用于不常常变更而查找频繁的有序列表.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.