唯一索引&主键(非聚簇表)
Key: tablePrefix{TableID}_indexPrefixSep{indexID}_indexedColumnsValue
Value: RowidindexPrefixSep: 索引位置。例如复合索引,2,表示第二个列
二级索引
Key: tablePrefix{TableID}_indexPrefixSep{indexID}_indexedColumnsValue_{RowID}
Value: null二级索引它并不唯一, 所以后面还有个rowid
索引结构示例

创建索引
- 与MySQL 索引创建语法保持兼容
- 创建索引时不会阻塞表的数据读写
create table t1 (id int not null primary key auto_increment,c1 int not null,key idx_t1_c1(c1));- 创建普通索引
alter table t1 add index idx_t1_c2(c2);- 创建唯一索引
alter table t1 add unique index uidx_t1_id(`id`);联合索引
联合索引在搜索使用时遵循最左匹配原则
create table t2(id int not null primary key auto_increment,
c1 int not null,
c2 int not null,
c3 int not null,
key idx_t2(c1,c2,c3)
);减小开销: 建一个联合索引(col1,col2,col3),实际相当于建了col1,(col1,col2),(col1,col2,col3)三个索引
可以有效使用索引的场景

部分使用索引的场景

不能使用索引的场景

 覆盖索引:当通过索引可以完整获取数据,则TiDB直接通过遍历索引获取数据,而无需回表,减少io操作。所以在真正的实际应用中,覆盖索引是主要的提升性能优化手段之一
索引表达式
索引表达式是一种特殊的索引,能将索引建立于表达式
 create index idx1 on t1(lower(col1));
可以通过查询变量tidb_allow_function_for_expression_index可得知哪些函数可以用于表达式索引
mysql> select @@tidb_allow_function_for_expression_index;
+-----------------------------------------------------+
| @@tidb_allow_function_for_expression_index          |
+-----------------------------------------------------+
| lower, md5, reverse, tidb_shard, upper, vitess_hash |
+-----------------------------------------------------+
1 row in set (0.01 sec)当查询语句中的表达式与表达式索引中的表达式一致时,优化器可以为该查询选择使用索引表达式

不可见索引
- invisible indexes 不会被查询优化器使用
- 不可见是仅仅对优化器而言的,不可见索引仍然可以被修改或删除
- 不允许将主键索引设为不可见
- alter index用于修改索引的可见性,设置为visible 或 invisible
create table t1 ( c1 int,c2 int,unique(c2));
create unique index c1 on t1(c1) visible;
alter table t1 alter index c1 invisible;例如可以评估某个SQL语句把索引拿掉但不能立即直接删掉,看会不会影响性能。
MySQL 兼容性
- 不支持fulltext,hash,spaital索引
- 不支持降序索引
- 无法向表中增删改clustered类型的主键
- 不支持类似mysql中提供的优化器开关use_invisible_indexes=on(将不可见索引重新设计为可见)
查看索引的Region分布
show table [table_name] index [index_name] regions [where clauseoptions]实验
创建主键索引、普通二级索引、联合唯一索引,并查看索引的分布情况
 1、创建表
mysql> CREATE TABLE index_order (
    -> id bigint(20) unsigned NOT NULL AUTO_random,
    -> code varchar(30) NOT NULL,
    -> order_no varchar(200) NOT NULL DEFAULT '',
    -> status int(4) NOT NULL,
    -> cancel_flag int(4) DEFAULT NULL,
    -> create_time datetime DEFAULT NULL,
    -> create_user varchar(32) DEFAULT NULL,
    -> PRIMARY KEY (id) clustered
    -> ) ENGINE=InnoDB;
Query OK, 0 rows affected, 1 warning (0.11 sec)
mysql> show create table index_order;
| index_order | CREATE TABLE `index_order` (
  `id` bigint(20) unsigned NOT NULL /*T![auto_rand] AUTO_RANDOM(5) */,
  `code` varchar(30) NOT NULL,
  `order_no` varchar(200) NOT NULL DEFAULT '',
  `status` int(4) NOT NULL,
  `cancel_flag` int(4) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  `create_user` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin |2、表中插入数据
mysql> insert into index_order(code,order_no,status,create_user,create_time) values(concat('CODE_',LPAD(round(rand()*1000),5,0)),uuid(),round((rand()*100)),concat('USERID_',LPAD(round(rand()*1000),5,0)),now()),(concat('CODE_',LPAD(round(rand()*1000),5,0)),uuid(),round((rand()*100)),concat('USERID_',LPAD(round(rand()*1000),5,0)),now()),(concat('CODE_',LPAD(round(rand()*1000),5,0)),uuid(),round((rand()*100)),concat('USERID_',LPAD(round(rand()*1000),5,0)),now()),(concat('CODE_',LPAD(round(rand()*1000),5,0)),uuid(),round((rand()*100)),concat('USERID_',LPAD(round(rand()*1000),5,0)),now()),(concat('CODE_',LPAD(round(rand()*1000),5,0)),uuid(),round((rand()*100)),concat('USERID_',LPAD(round(rand()*1000),5,0)),now());
Query OK, 5 rows affected (0.02 sec)
Records: 5  Duplicates: 0  Warnings: 0
mysql> insert into index_order(code,order_no,status,create_user,create_time) values(concat('CODE_',LPAD(round(rand()*1000),5,0)),uuid(),round((rand()*100)),concat('USERID_',LPAD(round(rand()*1000),5,0)),now()),(concat('CODE_',LPAD(round(rand()*1000),5,0)),uuid(),round((rand()*100)),concat('USERID_',LPAD(round(rand()*1000),5,0)),now()),(concat('CODE_',LPAD(round(rand()*1000),5,0)),uuid(),round((rand()*100)),concat('USERID_',LPAD(round(rand()*1000),5,0)),now()),(concat('CODE_',LPAD(round(rand()*1000),5,0)),uuid(),round((rand()*100)),concat('USERID_',LPAD(round(rand()*1000),5,0)),now()),(concat('CODE_',LPAD(round(rand()*1000),5,0)),uuid(),round((rand()*100)),concat('USERID_',LPAD(round(rand()*1000),5,0)),now());
Query OK, 5 rows affected (0.01 sec)
Records: 5  Duplicates: 0  Warnings: 0
mysql> select count(*) from index_order;
+----------+
| count(*) |
+----------+
|       10 |
+----------+
1 row in set (0.01 sec)3、将表index_order的regions手工打散
mysql> split table index_order between (0) and (9223372036854775807) regions 3;
+--------------------+----------------------+
| TOTAL_SPLIT_REGION | SCATTER_FINISH_RATIO |
+--------------------+----------------------+
|                  2 |                    1 |
+--------------------+----------------------+
1 row in set (0.22 sec)4、查看表index_order的regions分布
mysql> show table index_order regions;
+-----------+----------------------------+----------------------------+-----------+-----------------+-------+------------+---------------+------------+----------------------+------------------+
| REGION_ID | START_KEY                  | END_KEY                    | LEADER_ID | LEADER_STORE_ID | PEERS | SCATTERING | WRITTEN_BYTES | READ_BYTES | APPROXIMATE_SIZE(MB) | APPROXIMATE_KEYS |
+-----------+----------------------------+----------------------------+-----------+-----------------+-------+------------+---------------+------------+----------------------+------------------+
|      5003 | t_74_                      | t_74_r_3074457345618258602 |      5004 |            1001 | 5004  |          0 |             0 |          0 |                    1 |                0 |
|      5005 | t_74_r_3074457345618258602 | t_74_r_6148914691236517204 |      5006 |            1001 | 5006  |          0 |             0 |          0 |                    1 |                0 |
|      1002 | t_74_r_6148914691236517204 |                            |      1003 |            1001 | 1003  |          0 |             0 |          0 |                    1 |                0 |
+-----------+----------------------------+----------------------------+-----------+-----------------+-------+------------+---------------+------------+----------------------+------------------+
3 rows in set (0.00 sec)5、创建普通二级索引
mysql> create index id_index_order_create_user on index_order(create_user);
Query OK, 0 rows affected (2.80 sec)6、查看索引regions的分布
mysql> show table index_order index id_index_order_create_user regions;
+-----------+-----------+----------------------------+-----------+-----------------+-------+------------+---------------+------------+----------------------+------------------+
| REGION_ID | START_KEY | END_KEY                    | LEADER_ID | LEADER_STORE_ID | PEERS | SCATTERING | WRITTEN_BYTES | READ_BYTES | APPROXIMATE_SIZE(MB) | APPROXIMATE_KEYS |
+-----------+-----------+----------------------------+-----------+-----------------+-------+------------+---------------+------------+----------------------+------------------+
|      5003 | t_74_     | t_74_r_3074457345618258602 |      5004 |            1001 | 5004  |          0 |          5188 |       4220 |                    1 |               10 |
+-----------+-----------+----------------------------+-----------+-----------------+-------+------------+---------------+------------+----------------------+------------------+
1 row in set (0.00 sec)7、创建联合唯一索引 idx_index_order_unique
mysql> create unique index idx_index_order_unique on index_order(code,order_no,id);
Query OK, 0 rows affected (2.81 sec)8、查看联合唯一索引的Regions分布
mysql> show table index_order index idx_index_order_unique regions;
+-----------+-----------+----------------------------+-----------+-----------------+-------+------------+---------------+------------+----------------------+------------------+
| REGION_ID | START_KEY | END_KEY                    | LEADER_ID | LEADER_STORE_ID | PEERS | SCATTERING | WRITTEN_BYTES | READ_BYTES | APPROXIMATE_SIZE(MB) | APPROXIMATE_KEYS |
+-----------+-----------+----------------------------+-----------+-----------------+-------+------------+---------------+------------+----------------------+------------------+
|      5003 | t_74_     | t_74_r_3074457345618258602 |      5004 |            1001 | 5004  |          0 |             0 |          0 |                    1 |               10 |
+-----------+-----------+----------------------------+-----------+-----------------+-------+------------+---------------+------------+----------------------+------------------+
1 row in set (0.00 sec)9、对联合唯一索引的regions进行split
mysql> split table index_order index idx_index_order_unique between ('CODE_00000') and ('CODE_99999') regions 4;
+--------------------+----------------------+
| TOTAL_SPLIT_REGION | SCATTER_FINISH_RATIO |
+--------------------+----------------------+
|                  5 |                    1 |
+--------------------+----------------------+
1 row in set (0.51 sec)10、查看联合唯一索引的Region分布:
mysql> show table index_order index idx_index_order_unique regions;
+-----------+---------------------------------------+---------------------------------------+-----------+-----------------+-------+------------+---------------+------------+----------------------+------------------+
| REGION_ID | START_KEY                             | END_KEY                               | LEADER_ID | LEADER_STORE_ID | PEERS | SCATTERING | WRITTEN_BYTES | READ_BYTES | APPROXIMATE_SIZE(MB) | APPROXIMATE_KEYS |
+-----------+---------------------------------------+---------------------------------------+-----------+-----------------+-------+------------+---------------+------------+----------------------+------------------+
|      5009 | t_74_i_2_                             | t_74_i_2_01434f44455f3272733f32724000 |      5010 |            1001 | 5010  |          0 |             0 |          0 |                    1 |                1 |
|      5011 | t_74_i_2_01434f44455f3272733f32724000 | t_74_i_2_01434f44455f34b4b57f34b48000 |      5012 |            1001 | 5012  |          0 |             0 |          0 |                    1 |                1 |
|      5013 | t_74_i_2_01434f44455f34b4b57f34b48000 | t_74_i_2_01434f44455f36f6f7bf36f6c000 |      5014 |            1001 | 5014  |          0 |             0 |          0 |                    1 |                1 |
|      5015 | t_74_i_2_01434f44455f36f6f7bf36f6c000 | t_74_i_3_                             |      5016 |            1001 | 5016  |          0 |             0 |          0 |                    1 |                1 |
+-----------+---------------------------------------+---------------------------------------+-----------+-----------------+-------+------------+---------------+------------+----------------------+------------------+
4 rows in set (0.01 sec)                










