mysql,索引命中,查询级别

mysql索引没法命中状况html

1,查询占表数据30%以上mysql

2,小表查询sql

3,规定不用索引查询数据库

4,查询条件给字符串加引号用索引,不然不用数据库设计

5,条件中用到or,除非涉及到的列都有索引不然不命中post

6,like 的  %在前不命中,在后命中性能

 

 

示例 explain select * from adminlogmysql索引

执行结果:
 
id select_type table partitjons type possible_keys key key_len ref row filtered Extra
1 SIMPLE adminlog   ALL         2 100  

select_type  :查询类型测试

simple简单查询   primary 主查询  UNION 第二个或者后面的查询语句。SUBQUERY : 子查询中的第一个select]大数据

table :输出结果的表

type:查询级别

type=ALL 全表扫描,

 type=index 索引全扫描,遍历整个索引来查询匹配的行
type=range 索引范围扫描,常见于 <,<=,>,>=,between,in等操做符。
  例 
    explain select * from adminlog where id>0 , 
    explain select * from adminlog where id>0 and id<=100
    explain select * from adminlog where id in (1,2) 
 
type=ref  使用非惟一索引或惟一索引的前缀扫描,返回匹配某个单独值的记录行。ref还常常出如今JOIN操做中
type=eq_ref 相似于ref,区别就在使用的索引是惟一索引,对于每一个索引键值,表中有一条记录匹配;简单来讲,说是多表链接中使用 主建或惟一健做为关联条件
 type=const/system 单表中最多有一个匹配行。主要用于比较primary key [主键索引]或者unique[惟一]索引,由于数据都是惟一的,因此性能最优。条件使用=。 

type=NULL 不用访问表或者索引,直接就可以获得结果

 

四、possible_keys : 可能使用的索引列表.

五、key : 实现执行使用索引列表
六、key_len : 索引的长度
七、ref : 显示使用哪一个列或常数与key一块儿从表中选择行。
八、row : 执行查询的行数,简单且重要,数值越大越很差,说明没有用好索引

 

 

索引类型

1.普通索引
是最基本的索引,它没有任何限制。它有如下几种建立方式:
(1)直接建立索引

CREATE INDEX index_name ON table(column(length))

(2)修改表结构的方式添加索引

ALTER TABLE table_name ADD INDEX index_name ON (column(length))

(3)建立表的时候同时建立索引

复制代码
CREATE TABLE `table` (
    `id` int(11) NOT NULL AUTO_INCREMENT ,
    `title` char(255) CHARACTER NOT NULL ,
    `content` text CHARACTER NULL ,
    `time` int(10) NULL DEFAULT NULL ,
    PRIMARY KEY (`id`),
    INDEX index_name (title(length))
)
复制代码

(4)删除索引

DROP INDEX index_name ON table

2,

2.惟一索引
与前面的普通索引相似,不一样的就是:索引列的值必须惟一,但容许有空值。若是是组合索引,则列值的组合必须惟一。它有如下几种建立方式:
(1)建立惟一索引

CREATE UNIQUE INDEX indexName ON table(column(length))

(2)修改表结构

ALTER TABLE table_name ADD UNIQUE indexName ON (column(length))

(3)建立表的时候直接指定

复制代码
CREATE TABLE `table` (
    `id` int(11) NOT NULL AUTO_INCREMENT ,
    `title` char(255) CHARACTER NOT NULL ,
    `content` text CHARACTER NULL ,
    `time` int(10) NULL DEFAULT NULL ,
    UNIQUE indexName (title(length))
);
复制代码

3.主键索引
是一种特殊的惟一索引,一个表只能有一个主键,不容许有空值。通常是在建表的时候同时建立主键索引:

CREATE TABLE `table` (
    `id` int(11) NOT NULL AUTO_INCREMENT ,
    `title` char(255) NOT NULL ,
    PRIMARY KEY (`id`)
);

4.组合索引
指多个字段上建立的索引,只有在查询条件中使用了建立索引时的第一个字段,索引才会被使用。使用组合索引时遵循最左前缀集合

ALTER TABLE `table` ADD INDEX name_city_age (name,city,age); 

5.全文索引
主要用来查找文本中的关键字,而不是直接与索引中的值相比较。fulltext索引跟其它索引大不相同,它更像是一个搜索引擎,而不是简单的where语句的参数匹配。fulltext索引配合match against操做使用,而不是通常的where语句加like。它能够在create table,alter table ,create index使用,不过目前只有char、varchar,text 列上能够建立全文索引。值得一提的是,在数据量较大时候,现将数据放入一个没有全局索引的表中,而后再用CREATE index建立fulltext索引,要比先为一张表创建fulltext而后再将数据写入的速度快不少。
(1)建立表的适合添加全文索引

复制代码
CREATE TABLE `table` (
    `id` int(11) NOT NULL AUTO_INCREMENT ,
    `title` char(255) CHARACTER NOT NULL ,
    `content` text CHARACTER NULL ,
    `time` int(10) NULL DEFAULT NULL ,
    PRIMARY KEY (`id`),
    FULLTEXT (content)
);
复制代码

(2)修改表结构添加全文索引

ALTER TABLE article ADD FULLTEXT index_content(content)

(3)直接建立索引

CREATE FULLTEXT INDEX index_content ON article(content)

4、缺点

1.虽然索引大大提升了查询速度,同时却会下降更新表的速度,如对表进行insert、update和delete。由于更新表时,不只要保存数据,还要保存一下索引文件。同时考虑索引的命中,先建表插入数据在建索引比建好索引插入数据快
2.创建索引会占用磁盘空间的索引文件。通常状况这个问题不太严重,但若是你在一个大表上建立了多种组合索引,索引文件的会增加很快。
索引只是提升效率的一个因素,若是有大数据量的表,就须要花时间研究创建最优秀的索引,或优化查询语句。

5、注意事项

使用索引时,有如下一些技巧和注意事项:

1.字段的区分度很是低,彻底没法区分会下降速度 ,由于值都相同 这样一来B+树会没有任何的子节点,像一根竹竿每一都匹配至关于,有几条记录就有几回io ,全部要注意 区分度低的字段不该该创建索引,不能加速查询反而下降写入效率,
2.索引不会包含有null值的列
只要列中包含有null值都将不会被包含在索引中,复合索引中只要有一列含有null值,那么这一列对于此复合索引就是无效的。因此咱们在数据库设计时不要让字段的默认值为null。
3.使用短索引
对串列进行索引,若是可能应该指定一个前缀长度。例如,若是有一个char(255)的列,若是在前10个或20个字符内,多数值是唯一的,那么就不要对整个列进行索引。短索引不只能够提升查询速度并且能够节省磁盘空间和I/O操做。
4.索引列排序
查询只使用一个索引,所以若是where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。所以数据库默认排序能够符合要求的状况下不要使用排序操做;尽可能不要包含多个列的排序,若是须要最好给这些列建立复合索引。
5.like语句操做
通常状况下不推荐使用like操做,若是非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引而like “aaa%”可使用索引。
6. .索引字段不能参加运算 select count(*) from usr where id * 12 = 120; #速度很是慢缘由在于 mysql须要取出全部列的id 进行运算以后才能判断是否成立 #解决方案 select count(*) from usr where id = 120/12; #速度提高了 由于在读取数据时 条件就必定固定了 至关于 select count(*) from usr where id = 10; 

7.and有索引 mysql并非从左往右傻傻的去查 而是找出一个区分度高的字段优先匹配 #改成范围匹配 ,or从左往右

8,.多字段联合索引 为何须要联合索引 案例: select count(*) from usr where name = "jack" and gender = "m" and id > 3 and email = "xxxx2@qq.com"; 假设全部字段都是区分度很是高的字段,那么除看id为谁添加索引都可以提高速度,可是若是sql语句中没有出现因此字段,那就没法加速查询,最简单的办法是为每一个字段都加上索引,可是索引也是一种数据,会占用内存空间,而且下降写入效率 此处就可使用联合索引, 联合索引最重要的是顺序 按照最左匹配原则 应该将区分度高的放在左边 区分度低的放到右边 #删除其余索引 drop index name_index on usr; drop index email_index on usr; #联合索引 create index mul_index on usr(email,name,gender,id); # 查询测试 select count(*) from usr where name = "xx" and id = 1 and email = "xx"; 只要语句中出现了最左侧的索引(email) 不管在前在后都能提高效率 drop index mul_index on usr; ``` 
 
 
 
物理角度上

1. 汇集索引(Clustered Index)

 

汇集索引决定数据在磁盘上的物理排序,一个表只能有一个汇集索引。

 

2. 非汇集索引(Non-clustered Index)

 

非汇集索引并不决定数据在磁盘上的物理排序,索引上只包含被创建索引的数据,以及一个行定位符 row-locator,这个行定位符,能够理解为一个汇集索引物理排序的指针,经过这个指针,能够找到行数据。

 

 
 
 
 

 

 

 

 

转载于:https://www.cnblogs.com/wrqysrt/p/10902335.html