mysql 索引- 笔记

索引

   mysql最常用的索引结构是btree(O(log(n))),但是总有一些情况下我们为了更好的性能希望能使用别的类型的索引。hash就是其中一种选择,例如我们在通过用户名检索用户id的时候,他们总是一对一的关系,用到的操作符只是=而已,假如使用hash作为索引数据结构的话,时间复杂度可以降到O(1)。不幸的是,目前的mysql版本(5.6)中,hash只支持MEMORY和NDB两种引擎,而我们最常用的INNODB和MYISAM都不支持hash类型的索引。


1、BTree索引:

BTree(多路搜索树,并不是二叉的)是一种常见的数据结构。使用BTree结构可以显著减少定位记录时所经历的中间过程,从而加快存取速度。按照翻译,B 通常认为是Balance的简称。这个数据结构一般用于数据库的索引,综合效率较高。

B-Tree索引可以被用在像=,>,>=,<,<=和BETWEEN这些比较操作符上。而且还可以用于LIKE操作符,只要它的查询条件是一个不以通配符开头的常量。

EXPLAIN select * from blog.my_user where `name` in ('rhythmk251','rhythmk2151','rhythmk7251','rhythmk685');
+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+
| 1 | SIMPLE | my_user | ALL | NULL | NULL | NULL | NULL | 778424 | Using where |
+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+
1 row in set

  

添加 idx_name 索引:

ALTER TABLE blog.`my_user`
ADD INDEX `idx_name` (`name`) USING BTREE ;mysql> EXPLAIN select * from blog.my_user where `name` in ('rhythmk251','rhythmk2151','rhythmk7251','rhythmk685');
+----+-------------+---------+-------+---------------+----------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+----------+---------+------+------+-------------+
| 1 | SIMPLE | my_user | range | idx_name | idx_name | 303 | NULL | 4 | Using where |
+----+-------------+---------+-------+---------------+----------+---------+------+------+-------------+mysql> EXPLAIN select * from blog.my_user where `name` LIKE 'rhythmk830%';
+----+-------------+---------+-------+---------------+----------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+----------+---------+------+------+-------------+
| 1 | SIMPLE | my_user | range | idx_name | idx_name | 303 | NULL | 11 | Using where |
+----+-------------+---------+-------+---------------+----------+---------+------+------+-------------+
1 row in set

  任何一个没有覆盖所有WHERE中AND级别条件的索引是不会被使用的。也就是说,要使用一个索引,这个索引中的第一列需要在每个AND组中出现。

mysql> EXPLAIN select * from blog.my_user where `name` LIKE 'rhythmk830%' or age>35;
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | my_user | ALL | idx_name | NULL | NULL | NULL | 7266 | Using where |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
1 row in set
mysql> EXPLAIN select * from blog.my_user where `name` LIKE 'rhythmk830%' and age>35;
+----+-------------+---------+-------+---------------+----------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+----------+---------+------+------+-------------+
| 1 | SIMPLE | my_user | range | idx_name | idx_name | 303 | NULL | 11 | Using where |
+----+-------------+---------+-------+---------------+----------+---------+------+------+-------------+
1 row in set

有时候mysql不会使用索引,即使这个在可用的情况下。例如当mysql预估使用索引会读取大部分的行数据时。(在这种情况下,一次全表扫描可能比使用索引更快,因为它需要更少的检索)。然而,假如语句中使用LIMIT来限定返回的行数,mysql则会使用索引。因为当结果行数较少的情况下使用索引的效率会更高。

mysql> EXPLAIN select * from blog.my_user where `name` <> 'rhythmk830' ;
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | my_user | ALL | idx_name | NULL | NULL | NULL | 7769 | Using where |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
1 row in setmysql> EXPLAIN select * from blog.my_user where `name` <> 'rhythmk830' limit 5;
+----+-------------+---------+-------+---------------+----------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+----------+---------+------+------+-------------+
| 1 | SIMPLE | my_user | range | idx_name | idx_name | 303 | NULL | 5658 | Using where |
+----+-------------+---------+-------+---------------+----------+---------+------+------+-------------+
1 row in set

2、Hash 索引特征:


Hash类型的索引有一些区别于以上所述的特征:
精确查找非常快(包括= <> 和in),其检索效率非常高,索引的检索可以一次定位,不像BTree 索引需要从根节点到枝节点,所以 Hash 索引的查询效率要远高于 B-Tree 索引。

不适合:

1、不适合模糊查询和范围查询(包括like,>,<,between……and等)。由于 Hash 索引比较的是进行 Hash 运算之后的 Hash 值,所以它只能用于等值的过滤,不能用于基于范围的过滤,因为经过相应的 Hash 算法处理之后的 Hash 值的大小关系,并不能保证和Hash运算前完全一样;
2、不适合排序,数据库无法利用索引的数据来提升排序性能,同样是因为Hash值的大小不确定;
3、复合索引不能利用部分索引字段查询,Hash 索引在计算 Hash 值的时候是组合索引键合并后再一起计算 Hash 值,而不是单独计算 Hash 值,所以通过组合索引的前面一个或几个索引键进行查询的时候,Hash 索引也无法被利用。


3、备注:

1、索引列需要根据业务判断 ,在where条件中出现的列。
2、使用索引需要考虑某列中值的分布,比如性别,搜索 “男/女” 都会得出大约一半的行,所有索引没有多大的用处。
3、使用短索引好处多多。对字符串进行索引的时候,应该指定一个前缀长度。索引长度小,节约索引空间及磁盘IO同时让索引,短的值比较起来更快,同时Mysql 可以在内存中存储更多的值。
4、利用最左前缀。创建一个多列索引,可起几个索引的作用。因为可利用索引最左边的列来匹配行。这样的列集称为最左前缀。
5、不要过度索引。 额外的索引需要占用空间,并降低写操作的性能。修改表的时候索引必须进行更新,有时可能需要重构,索引越多时间越长。索引太多,也可能导致MYSQL选择不到最优索引。
6、INNODB 存储引擎,记录优先按主键保存,如果没有主键,但是有唯一索引那么就按唯一索引列保存。如果两者都没有,那么表中会生成一个内部列。按照这个列的顺序保存,InnoDB普通索引都会保存主键,所以主键要尽可能选择较短的数据类型。

 7、尽量避免NULL:应该指定列为NOT NULL,除非你想存储NULL。在MySQL中,含有空值的列很难进行查询优化,因为它们使得索引、索引的统计信息以及比较运算更加复杂。你应该用0、一个特殊的值或者一个空串代替空值。

 8、使用--查看当前session所有已产生的profile  
      

mysql> show profiles;  

  

转载于:https://www.cnblogs.com/rhythmK/p/5352714.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/357407.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在编译器中鼠标光标变成下横线的解决办法

适用于各种智能编译器&#xff0c;HB-X,VSCode,ST3,IDEA等。 问题&#xff1a; 按一下键盘上的&#xff0c;insert 键。

java自定义序列化_Java中的自定义国际化(i18n)

java自定义序列化国际化&#xff08;i18n&#xff09;在我们的软件项目中非常重要。 它主要带来以下好处&#xff1a; 将UI字符串外部化为代码文件以外的外部文件&#xff0c;以及易于管理的UI内容。 支持多种语言。 在这篇文章中&#xff0c;将为Eclipse和Java项目提供一个i…

如何科学高效的学习Web前端开发?

近几年,web前端开发工程师越来越火了,薪资待遇也快接近后端开发工程师了。很多准备入行前端开发工程师的小伙伴们,不知道准备得怎么样了呢? 有的朋友在想方设法的学习,争取在年后的金九银十能靠实力找到一份满意的工作!有的小伙伴在准备准备回家过个团圆年,来年再战!还有…

Apache Drill:如何创建新功能?

Apache Drill允许用户使用ANSI SQL探索任何类型的数据。 这很棒&#xff0c;但是Drill的作用远远不止于此&#xff0c;它允许您创建自定义函数来扩展查询引擎。 这些自定义功能具有任何Drill基本操作的所有性能&#xff0c;但是允许执行这些性能会使编写这些功能比您期望的要复…

Json的访问

JSON&#xff1a;JavaScript 对象表示法&#xff08;JavaScript Object Notation&#xff09; 写法&#xff1a;名称/值对 访问方法&#xff1a;可以通过 data.名称 访问&#xff0c;也可以通过 data[名称] 访问 注意&#xff1a;名称加不加引号都可以&#xff0c;但是加引号安…

让一个文字在背景图片水平居中的方法

最近工作中在做那个可视化大屏&#xff0c;图中用到了大量的装饰图片&#xff0c;下面看一下文字怎么在图片中水平居中。 这个方法比较好用&#xff0c;其他的方法嵌入太多可能不是特别好使&#xff0c;尤其嵌入到多个框架中。 html <!DOCTYPE html> <html><h…

Objective-C中,ARC下的 strong和weak指针原理解释

Objective-C中&#xff0c;ARC下的 strong和weak指针原理解释 提示&#xff1a;本文中所说的"实例变量"即是"成员变量"&#xff0c;"局部变量"即是"本地变量" 一、简介 ARC是自iOS 5之后增加的新特性&#xff0c;完全消除了手动管理内…

elementui去掉表格所有边框

/deep/.el-table {border: 0;th,tr,td{border: 0;background-color: #fff;}&::before {height: 0px;}&::after {width: 0;}.el-table__fixed:before {height: 0;}}

cdi 2.7.5_集成测试CDI 1.0和Spring 3.1中的作用域bean

cdi 2.7.5在这篇博客文章中&#xff0c;我描述了如何在Spring和CDI中使用作用域bean进行集成测试。 一切都用小代码示例进行说明。 使用范围进行集成测试并不是特别容易。 想象一下存在于会话范围内的bean&#xff0c;例如UserCredentials 。 在集成测试中&#xff0c;通常没有…

工作流编写教程

介绍 ONES中使用了flowchart.js作为前端展示&#xff0c;并且扩展了flowchart.js的流程描述语言。flowchart.js 参见&#xff1a; https://github.com/adrai/flowchart.js 描述语言分为三部分&#xff0c;使用\n\n(空一行)作为分割&#xff0c;分别是节点定义、执行流程描述、节…

elementui设置表头与表格(左对齐,背景颜色,字体大小等)

headerStyle控制表头&#xff0c;finalCellStyle控制表格 html <div class"table1"><el-tablesize"mini":data"tableDataLeft"borderstripe:default-sort"defaultSort":max-height"tableMaxH":header-cell-style&…

使用LocalTestServer对HTTP调用进行单元测试

有时候&#xff0c;当您正在对远程服务器进行HTTP调用的单元测试代码时。 您可能正在使用诸如ApachesHttpClient或Spring的RestTemplate之类的库。 当然&#xff0c;您不想依靠远程服务进行单元测试。 除了涉及的开销&#xff08;记住单元测试应该是快速的&#xff09;之外&am…

PHP header函数大全

PHP header函数大全 header(Content-Type: text/html; charsetutf-8); header(Location: http://www.php-note.com/); <?php // fix 404 pages: header(HTTP/1.1 200 OK);// set 404 header: header(HTTP/1.1 404 Not Found);// set Moved Permanently header (good for re…

JS提升(hoisting)

近期在学习js&#xff0c;了解到js的一个名词&#xff0c;就是hoisting&#xff0c;进而了解了下js的解析机制 详情可参考&#xff1a;http://www.runoob.com/js/js-hoisting.html js的解析过程分为两个阶段&#xff1a;编译阶段和执行阶段 编译阶段&#xff1a;即我们常说的…

【Java从入门到天黑|01】SE入门之Java的前生今世

大家好,我是孙叫兽,微信公众号【孙叫兽杂谈】,本期给大家分享一下JavaSE的入门部分之Java的前生今世。 Java : 一个帝国的诞生 C语言帝国的统治 现在是公元1995年, C语言帝国已经统治了我们20多年, 实在是太久了。 1972年, 随着C语言的诞生和Unix的问世, 帝国

前端-html、css

HTML一、html简介超级文本标记语言是标准通用标记语言下的一个应用&#xff0c;也是一种规范&#xff0c;一种标准&#xff0c;它通过标记符号来标记要显示的网页中的各个部分。网页文件本身是一种文本文件&#xff0c;通过在文本文件中添加标记符&#xff0c;可以告诉浏览器如…

在Java EE组件中使用骆驼路线

从现在开始我一直在与Camel合作&#xff0c;我真的很喜欢它的简单性。 在Java EE之上始终使用它一直是一个挑战&#xff0c;而我最近发表的有关如何做到这一点的演讲之一以及Java EE中引导Camel的不同方法实际上建议使用WildFly-Camel Subsystem 。 在正在进行的系列文章中&…

【Java从入门到天黑|02】SE入门之Java基础

大家好,我是孙叫兽,微信公众号【孙叫兽杂谈】,本期给大家分享一下JavaSE的入门部分之Java基础 目录 注释 标识符 数据类型 类型转换 变量,常量 运算符

webpack入门

遇到问题首先到github项目的Issues中&#xff0c;检索一下相关问题&#xff0c;比在百度谷歌上直接搜索非官方解决方案好得多。 1、npm init 生成 package.json 2、npm i -D webpack 生成 # npm i -D 是 npm install --save-dev 的简写&#xff0c;是指安装模块并保存到 packa…

接口自动化 基于python+Testlink+Jenkins实现的接口自动化测试框架

基于pythonTestlinkJenkins实现的接口自动化测试框架 by:授客 QQ&#xff1a;1033553122 博客&#xff1a;http://blog.sina.com.cn/ishouke 欢迎加入软件性能测试交流QQ群&#xff1a;7156436 目录 1、 开发环境... 1 2、 主要功能逻辑介绍... 1 3、 框架…