今儿啊,洲际哥给你们带来两个8.0的新特性数据库
schema_unused_indexes表,这个表有三个列分别是object_schema、object_name、index_name函数
对于这些索引,一般来讲,就是删掉,可是直接删除有问题啊,可能如今没用到,过段时间要用啊优化
但在MySQL 8.0中咱们能够先将索引设置为invisible,优化器就不会走这个索引,跑一段时间观察对业务有没有影响,若是没有影响再把这个索引删掉code
(root@localhost) [sys]> select * from schema_unused_indexes limit 3; +---------------+-------------+---------------------+ | object_schema | object_name | index_name | +---------------+-------------+---------------------+ | dbt3 | customer | i_c_nationkey | | dbt3 | lineitem | i_l_shipdate | | dbt3 | lineitem | i_l_suppkey_partkey | +---------------+-------------+---------------------+ 3 rows in set (0.00 sec)
alter table xxx alter index_name invisible/visible;
(root@localhost) [dbt3]> explain select * from orders where o_custkey = 1 order by o_orderDate,o_orderStatus; +----+-------------+--------+------------+------+---------------+-------------+---------+-------+------+----------+---------------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+--------+------------+------+---------------+-------------+---------+-------+------+----------+---------------------------------------+ | 1 | SIMPLE | orders | NULL | ref | i_o_custkey | i_o_custkey | 5 | const | 6 | 100.00 | Using index condition; Using filesort | +----+-------------+--------+------------+------+---------------+-------------+---------+-------+------+----------+---------------------------------------+ 1 row in set, 1 warning (0.00 sec) (root@localhost) [dbt3]> alter table orders add index idx_a_b_c(o_custkey,o_orderDate,o_orderStatus); Query OK, 0 rows affected (6.33 sec) Records: 0 Duplicates: 0 Warnings: 0 (root@localhost) [dbt3]> explain select * from orders where o_custkey = 1 order by o_orderDate,o_orderStatus; +----+-------------+--------+------------+------+-----------------------+-----------+---------+-------+------+----------+-----------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+--------+------------+------+-----------------------+-----------+---------+-------+------+----------+-----------------------+ | 1 | SIMPLE | orders | NULL | ref | i_o_custkey,idx_a_b_c | idx_a_b_c | 5 | const | 6 | 100.00 | Using index condition | +----+-------------+--------+------------+------+-----------------------+-----------+---------+-------+------+----------+-----------------------+ 1 row in set, 1 warning (0.06 sec) (root@localhost) [dbt3]> explain select * from orders where o_custkey = 1 order by o_orderDate DESC,o_orderStatus; +----+-------------+--------+------------+------+-----------------------+-------------+---------+-------+------+----------+---------------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+--------+------------+------+-----------------------+-------------+---------+-------+------+----------+---------------------------------------+ | 1 | SIMPLE | orders | NULL | ref | i_o_custkey,idx_a_b_c | i_o_custkey | 5 | const | 6 | 100.00 | Using index condition; Using filesort | +----+-------------+--------+------------+------+-----------------------+-------------+---------+-------+------+----------+---------------------------------------+ 1 row in set, 1 warning (0.00 sec)
综上所述:到5.7为止,全部的排序必须是一个方向(A,B,C),由于索引默认都是(A asc,B asc,C asc)这种,若是DESC就得从新排序,即方向不一致就行不通排序
可是线上咱们常常会碰到这种方向不一致的场景,怎么办呢?索引
方案一:8.0 新特性ip
alter table orders add index idx_cust_data_status (o_custkey,o_orderDate DESC,o_orderStatus);
其实在5.7中也能够这样执行,可是会把desc忽略掉,没用it
方案二:虚拟列
目前你们基本上还用的5.7,咱们这边用下面这种函数索引(虚拟列)的方法来实现一下需求io
alter tablename add column as (function(column)) virtual/stored;
virtual 每次访问这个列须要一次额外计算,不占任何存储空间,只是一个计算获得的列,可是能够在上面增长一个索引,这个索引是占空间的,stored 在磁盘上占据空间table
一般用virtual,不用stored
用函数表达式建立一个虚拟列,datediff是一个日期差,化降序为升序 (root@localhost) [dbt3]> alter table orders add column o_orderdate2 int as (datediff('2099-01-01',o_orderdate)) virtual; Query OK, 0 rows affected (0.94 sec) Records: 0 Duplicates: 0 Warnings: 0 在这个虚拟列上加一个索引 (root@localhost) [dbt3]> alter table orders add index idx_cust_date_status (o_custkey,o_orderdate2,o_orderstatus); Query OK, 0 rows affected (8.99 sec) Records: 0 Duplicates: 0 Warnings: 0 (root@localhost) [dbt3]> explain select * from orders where o_custkey = 1 order by o_orderDate2,o_orderStatus; +----+-------------+--------+------------+------+--------------------------------------------+----------------------+---------+-------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+--------+------------+------+--------------------------------------------+----------------------+---------+-------+------+----------+-------------+ | 1 | SIMPLE | orders | NULL | ref | i_o_custkey,idx_a_b_c,idx_cust_date_status | idx_cust_date_status | 5 | const | 6 | 100.00 | Using where | +----+-------------+--------+------------+------+--------------------------------------------+----------------------+---------+-------+------+----------+-------------+ 1 row in set, 1 warning (0.00 sec)
这个作法只有5.7版本才能用,由于虚拟列和函数索引都是5.7才支持的
这个知识点先了解一下便可
背景
订单status上是否须要建索引,三种状态 0 1 2
倾斜:大部分状态是已完成,查询条件大部分时候是未完成状态,而这种未完成的状态又是不多量的,
若是一共1000w,未完成的只有10w,这样去取是符合B+ tree的条件,从大量数据取小部分数据,这时候自己是有意义的,可是若是去作一些比较复杂的查询,数据库的优化器可能会出错,由于他不知道索引是倾斜的,致使它在选择上有问题
5.7以前,优化器不能感知索引倾斜,若是优化器的执行计划出现小误差,去看下他使用的哪一个索引是否存在倾斜,若是存在那也没办法,后面8.0可能会改进
(root@localhost) [dbt3]> explain select * from lineitem where l_orderkey=1; +----+-------------+----------+------------+------+--------------------------------------------+---------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+----------+------------+------+--------------------------------------------+---------+---------+-------+------+----------+-------+ | 1 | SIMPLE | lineitem | NULL | ref | PRIMARY,i_l_orderkey,i_l_orderkey_quantity | PRIMARY | 4 | const | 6 | 100.00 | NULL | +----+-------------+----------+------------+------+--------------------------------------------+---------+---------+-------+------+----------+-------+ 1 row in set, 1 warning (0.11 sec) 优化器选择了pk 咱们也能够强制走索引,但不是很建议这么作 (root@localhost) [dbt3]> explain select * from lineitem force index(i_l_orderkey) where l_orderkey=1; +----+-------------+----------+------------+------+---------------+--------------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+----------+------------+------+---------------+--------------+---------+-------+------+----------+-------+ | 1 | SIMPLE | lineitem | NULL | ref | i_l_orderkey | i_l_orderkey | 4 | const | 6 | 100.00 | NULL | +----+-------------+----------+------------+------+---------------+--------------+---------+-------+------+----------+-------+ 1 row in set, 1 warning (0.00 sec)