博客:

https://blog.csdn.net/tongdanping/article/details/79878302#%E4%B8%89%E3%80%81%E7%B4%A2%E5%BC%95%E7%9A%84%E5%88%86%E7%B1%BB

https://blog.csdn.net/u012954706/article/details/81241049

一、什么是索引?为什么要建立索引?

1、索引是表的目录,在查找内容之前可以先在目录中查找索引位置,以此快速定位查询数据。对于索引,会保存在额外的文件中。
2、索引,是数据库中专门用于帮助用户快速查询数据的一种数据结构。类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置,然后直接获取即可。

1、索引选取类型
1、越小的数据类型通常更好:越小的数据类型通常在磁盘、内存和CPU缓存中都需要更少的空间,处理起来更快。

2、简单的数据类型更好:整型数据比起字符,处理开销更小,因为字符串的比较更复杂。

3、尽量避免NULL:应该指定列为NOT nuLL,在MySQL中, 含有空值的列很难进行查询优化,因为它们使得索引、索引的统计信息以及比较运算更加复杂

2、什么场景不适合创建索引

第一,对于那些在查询中很少使用或者参考的列不应该创建索引。这是因 为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。

第二,对于那 些只有很少数据值的列也不应该增加索引。因为本来结果集合就是相当于全表查询了,所以没有必要。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比 例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。

第三,对于那些定义为text, image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。

第四,当修改性能远远大于检索性能时,不应该创建索 引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因 此,当修改性能远远大于检索性能时,不应该创建索引。

第五,不会出现在where条件中的字段不该建立索引。

3、什么样的字段适合创建索引

1、表的主键、外键必须有索引;外键是唯一的,而且经常会用来查询

2、数据量超过300的表应该有索引;

3、经常与其他表进行连接的表,在连接字段上应该建立索引;经常连接查询,需要有索引

4、经常出现在Where子句中的字段,加快判断速度,特别是大表的字段,应该建立索引,建立索引,一般用在select ……where f1 and f2 ,我们在f1或者f2上建立索引是没用的。只有两个使用联合索引才能有用

5、经常用到排序的列上,因为索引已经排序。

6、经常用在范围内搜索的列上创建索引,因为索引已经排序了,其指定的范围是连续的

二、索引优缺点
1、优点
索引由数据库中一列或多列组合而成,其作用是提高对表中数据的查询速度
索引的优点是可以提高检索数据的速度

【可以快速检索,减少I/O次数,加快检索速度;根据索引分组和排序,可以加快分组和排序;】

2、缺点
索引的缺点是创建和维护索引需要耗费时间
索引可以提高查询速度,会减慢写入速度

索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。

【索引本身也是表,因此会占用存储空间,一般来说,索引表占用的空间的数据表的1.5倍;索引表的维护和创建需要时间成本,这个成本随着数据量增大而增大;构建索引会降低数据表的修改操作(删除,添加,修改)的效率,因为在修改数据表的同时还需要修改索引表;】

3、索引分类
(1),普通索引:
仅加速查询 最基本的索引,没有任何限制,是我们大多数情况下使用到的索引。
CREATE INDEX index_name on user_info(name) ;
1

注意:

1、索引需要占用磁盘空间,因此在创建索引时要考虑到磁盘空间是否足够

2、创建索引时需要对表加锁,因此实际操作中需要在业务空闲期间进行

1、创建表的时候同时创建索引

create table healerjean (
id bigint() NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '主键',
name VARCHAR() NOT NULL COMMENT '姓名',
email VARCHAR() NOT NULL COMMENT '邮箱',
message text DEFAULT NULL COMMENT '个人信息',
INDEX index_name (name) COMMENT '索引name'
) COMMENT = '索引测试表';

2、在存在表上创建索引

create index index_name on healerjean(name)

3、注意

对于创建索引时如果是blob 和 text 类型,必须指定length。

create index ix_extra on in1(message());

alter table employee add index emp_name (name);

4、删除索引

drop index_name on healerjean;

alter TABLE users  drop index  name_index ;

5、查看索引

show index from healerjean;

(2),主键索引

即主索引,根据主键pk_clolum(length)建立索引,不允许重复,不允许空值;

ALTER TABLE 'table_name' ADD PRIMARY KEY pk_index('col');

(3),唯一索引
与普通索引类型,不同的是:加速查询 + 列值唯一(可以有null)
CREATE UNIQUE INDEX mail on user_info(name) ;
1

(4),全文索引:
全文索引(FULLTEXT)仅可以适用于MyISAM引擎的数据表;作用于CHAR、VARCHAR、TEXT数据类型的列。
(5),组合索引:

ALTER TABLE 'table_name' ADD INDEX index_name('col1','col2','col3');

将几个列作为一条索引进行检索,使用最左匹配原则。

*遵循“最左前缀”原则,把最常用作为检索或排序的列放在最左,依次递减,组合索引相当于建立了col1,col1col2,col1col2col3三个索引,而col2或者col3是不能使用索引的。

*在使用组合索引的时候可能因为列名长度过长而导致索引的key太大,导致效率降低,在允许的情况下,可以只取col1和col2的前几个字符作为索引。

ALTER TABLE 'table_name' ADD INDEX index_name(col1(),col2());

表示使用col1的前4个字符和col2的前3个字符作为索引。

三、正确使用索引

1、对于创建的多列索引,只要查询的条件中用到了最左边的列,索引一般就会被使用

(1)、首先按 company_id,moneys 的顺序创建一个复合索引,具体如下:

mysql> create index ind_sales2_companyid_moneys on sales2(company_id,moneys);
Query OK, rows affected (0.03 sec)
Records: Duplicates: Warnings:

(2)然后按 company_id 进行表查询,具体如下:

mysql> explain select * from sales2 where company_id = \G;
*************************** . row ***************************
id:
select_type: SIMPLE
table: sales2
type: ref
possible_keys: ind_sales2_companyid_moneys
208key: ind_sales2_companyid_moneys
key_len:
ref: const
rows:
Extra: Using where
row in set (0.00 sec)

(3)可以发现即便 where 条件中不是用的 company_id 与 moneys 的组合条件,索引仍然能用到,这就是索引的前缀特性。

(4)但是如果只按 moneys 条件查询表,那么索引就不会被用到,具体如下:

mysql> explain select * from sales2 where moneys = \G;
*************************** . row ***************************
id:
select_type: SIMPLE
table: sales2
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows:
Extra: Using where
row in set (0.00 sec)

2、对于使用 like 的查询,后面如果是常量并且只有%号不在第一个字符,索引才可能会被使用:

1、 可以发现第一个例子没有使用索引,而第二例子就能够使用索引,
2、 区别就在于“%”的位置不同,前者把“%”放到第一位就不能用到索引,而后者没有放到第一位就使用了索引。

mysql> explain select * from company2 where name like '%3'\G;
*************************** . row ***************************
id:
select_type: SIMPLE
table: company2
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows:
Extra: Using where
row in set (0.00 sec)
mysql> explain select * from company2 where name like '3%'\G;
*************************** . row ***************************
id:
select_type: SIMPLE
table: company2
type: range
209possible_keys: ind_company2_name
key: ind_company2_name
key_len:
ref: NULL
rows:
Extra: Using where
row in set (0.00 sec)

3、如果列名,记得是列的名字,是索引,使用 column_name is null 将使用索引。【 没懂啊】

mysql> explain select * from company2 where name is null\G;
*************************** . row ***************************
id:
select_type: SIMPLE
table: company2
type: ref
possible_keys: ind_company2_name
key: ind_company2_name
key_len:
ref: const
rows:
Extra: Using where
row in set (0.00 sec)

4、如果对大的文本进行搜索,使用全文索引而不用使用 like ‘%…%’。

四、存在索引,但是不引用

1、如果 MySQL 估计使用索引比全表扫描更慢,则不使用索引。例如,如果列key_part1 均匀分布在 1 和 100 之间,下列查询中使用索引就不是很好:

SELECT * FROM table_name where key_part1 > 1 and key_part1 < 90;

2、如果使用 MEMORY/HEAP 表并且 where 条件中不使用“=”进行索引列,那么不会用到索引。heap 表只有在“=”的条件下才会使用索引。

3、用 or 分割开的条件,如果 or 前的条件中的列有索引,而后面的列中没有索引,那么涉及到的索引都不会被用到,例如:,必须or前后都有索引才能被使用,而且必须是单独索引。

mysql> show index from sales\G;
*************************** . row ***************************
Table: sales
Non_unique:
Key_name: ind_sales_year
Seq_in_index:
Column_name: year
210Collation: A
Cardinality: NULL
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
row in set (0.00 sec)

4、如果列是字符型,,传入的是数字,则不上‘’不会使用索引

mysql> explain select * from company2 where name = \G;
*************************** . row ***************************
id:
select_type: SIMPLE
table: company2
type: ALL
possible_keys: ind_company2_name
key: NULL
key_len: NULL
ref: NULL
rows:
Extra: Using where
row in set (0.00 sec) mysql> explain select * from company2 where name = ''\G;
*************************** . row ***************************
id:
select_type: SIMPLE
table: company2
type: ref
possible_keys: ind_company2_name
key: ind_company2_name
key_len:
ref: const
rows:
Extra: Using where
row in set (0.00 sec)

最新文章

  1. (DNS被劫持所导致的)QQ音乐与视频网页打开很慢的解决方法
  2. tomcat 配置客户端证书认证
  3. drupal记录(一)
  4. 设备文件的创建mknod
  5. Hibernate监听器
  6. linux系统日志使用
  7. &amp;lt;Android&amp;gt;从窗口泄漏谈android:configChanges属性
  8. poj 1201 Interval (查分约束)
  9. poj 3273 Monthly Expence 简单二分
  10. 彻底理解浮动float CSS浮动详解 清除浮动的方法
  11. (@WhiteTaken)设计模式学习——简单工厂
  12. ADALINE模型
  13. 在nagios中监控windows主机系统地址的状态
  14. Chapter 5 Blood Type——8
  15. java maven web 项目启动之后,访问所有页面为空白,不是404!!!
  16. JavaScript HTML DOM - 改变 CSS
  17. 《FPGA全程进阶---实战演练》第五章 基于74HC595的LED操作
  18. 昂达 v891 连接上adb 调试
  19. zuul超时及重试配置
  20. s3cmd在配置后使用时提示ERROR: S3 error: 403 (InvalidAccessKeyId): The AWS Access Key Id you provided does not exist in our records.

热门文章

  1. 提高js性能的方法
  2. mybatis连接mysql(jdbc)常见问题
  3. jsp动作标签学习
  4. VMware下的Ubuntu16设置连接主机网络,设置主机下可以通过xshell访问 VMware下的Ubuntu
  5. Java远程调用Linux脚本
  6. python如何在一个for循环中遍历多个列表
  7. java 里没有友元函数怎么办
  8. swoole使用内存
  9. ubuntu14.04安装32位库
  10. bootstrap-table 实现父子表