索引是sql语句优化的一部分,在实际的应用中当我们存在大量的数据需要查询的时候,提升查询效率最好的方式就是建立有效的索引,那索引是什么,如何用,并且如何去建立一个有效的索引,这些问题本篇可以给你解惑!
1.查询表中所含有的索引:
show index from tb_item;
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
| tb_item | 0 | PRIMARY | 1 | id | A | 914 | NULL | NULL | | BTREE | | | YES |
| tb_item | 1 | cid | 1 | cid | A | 2 | NULL | NULL | | BTREE | | | YES |
| tb_item | 1 | status | 1 | status | A | 1 | NULL | NULL | | BTREE | | | YES |
| tb_item | 1 | updated | 1 | updated | A | 46 | NULL | NULL | | BTREE | | | YES |
2.创建索引:
create index idx_status on tb_item(status);
3.删除索引:
drop index idex_stautus on tb_item;
索引是对排好序的快速查找数据结构,对where和order by都有一定的影响。索引本身很大,不可能存放在内存中,索引是以文件的方式存储在磁盘上。目的是为了提高查找的效率。
聚集索引:数据行的物理顺序与列值(一般是主键的那一列)的逻辑顺序相同,一个表中只能拥有一个聚集索引。
非聚集索引:该索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同,一个表中可以拥有多个非聚集索引。
更多具体的内容可以参考博客:聚集索引与非聚集索引的总结
1.btree树
2.hash树
MyISAM索引结构采用了b+tree,INNODB采用也是b+tree。虽然结构一致但是实现的方案确实不一样的。之前的学习中我们知道MyISAM数据库目录下存在了myi,myd,frm,innodb文件目录有idb,frm。这也就是说明MyISAM的索引文件和数据文件是分开存放的,
具体的实现方案:
.MyISAM叶节点的data域存放的是数据记录的地址,索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址,读取相应数据记录。
与MyISAM索引的不同是InnoDB的辅助索引data域存储相应记录主键的值而不是地址。如果是主键索引,那么记录的主键的值本身就是查询到的值,但是InnoDB的所有辅助索引都引用主键作为data域索引,辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录
1.主键自动建立唯一索引
2.频繁作为查询条件的字段应该创建索引
3.查询中与其他表管理字段,外键关系建立索引
4.不频繁更新,where条件中用到的字段创建创建索引
5.查询中排序的字段
6.数据量大,并且重复数据不多
explain select id,cid from tb_item where cid=76 order by updated;
展示结果是:
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+------+---------------+------+---------+-------+------+----------+---------------------------------------+
| 1 | SIMPLE | tb_item | NULL | ref | cid | cid | 8 | const | 213 | 100.00 | Using index condition; Using filesort |
explain分析计划中最重要的是id,type,key,extra,其中extra为using filesort是最糟糕的一种情况,所以优化方法是创建复合索引:
create index index_cu on tb_item(cid,updated);
再次执行分析结果如下:
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+------+---------------+----------+---------+-------+------+----------+--------------------------+
| 1 | SIMPLE | tb_item | NULL | ref | cid,index_cu | index_cu | 8 | const | 213 | 100.00 | Using where; Using index |
+----+-------------+---------+------------+------+---------------+----------+---------+-------+------+----------+--------------------------
发现extra指标变成了using index是最好的一种情况。
但是如果cid的条件不是一个const,变成范围值,执行的结果又会发生变化:
mysql> explain select id,cid from tb_item where cid>76 order by updated;
+----+-------------+---------+------------+-------+---------------+----------+---------+------+------+----------+------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+-------+---------------+----------+---------+------+------+----------+------------------------------------------+
| 1 | SIMPLE | tb_item | NULL | range | cid,index_cu | index_cu | 8 | NULL | 721 | 100.00 | Using where; Using index; Using filesort |
+----+-------------+---------+------------+-------+---------------+----------+---------+------+------+----------+------------------------------------------+
1 row in set, 1 warning (0.00 sec)
extra指标再次变成了using filesort,所以证明where条件是一个范围值那么会导致以后的索引失效;
献上索引优化的口诀:
全值索引我最爱,最左前缀要遵守
带头大哥不能死,中间兄弟不能断
索引列上少计算,范围之后全失效
like百分写最右,覆盖索引不写*
不等空值还有or,索引失效要少用
var引号不能丢,sql高级也不难
【参考博客】
关于索引的使用暂时讲解到这里,如果有疑问请及时联系我!感谢浏览!