索引一般用于在数据规模大时对查询进行优化的一种机制,对于一般的查询来说,mysql会去遍历整个表,来查询符合要求的结果;

如果借助于mysql索引,mysql会将要索引的字段按照一定的算法进行处理,并生成一个类似于书本目录的文件存放在相应的位置,这样在查询时,mysql会先去查找这些"目录",然后根据这些"目录"来快速定位所需记录的位置,这样的查找不用遍历整个记录集,速度自然会很快,对于海量数据尤其如此。

注意,在向存在索引的表中插入数据时,因为要维护索引信息,要比不存在索引的表慢一些,因此当数据量大时,可以考虑在插入完数据之后再建立索引。

索引分为单列索引和组合索引,对于这两种索引,分别介绍其索引优化问题。

1、单列索引

单列所有只包含一个字段,一个表可以包含多个单列索引,但是不要把这个和组合索引混淆。利用以下sql创建测试表:

复制代码 代码示例:

--创建包含单列索引的index_test_single_a表

create table `index_test_a` (

`id` int(11) not null auto_increment,

`title` char(255) character set utf8 not null,

`content` text character set utf8,

`num` int(11) default null,

primary key (`id`),

unique key `indexname` (`title`),

unique key `numindex` (`num`)

) engine=innodb auto_increment=10000 default charset=latin1;

--创建不包含单列索引的index_test_single_b表

create table `index_test_b` (

`id` int(11) not null auto_increment,

`title` char(255) character set utf8 not null,

`content` text character set utf8,

`num` int(11) default null,

primary key (`id`)

) engine=innodb auto_increment=10000 default charset=latin1;

其中a表包含title的单列索引,b表的title字段不存在索引,但是两个表都有一个主键id,其实主键也是索引的一种,这个会在后面详细解释。

写程序向这两个表中各导入10000条数据,然后就可以测试了。

1.1、测试查询索引字段所用的时间,代码如下:

复制代码 代码示例:

//phpinfo();

ini_set('max_execution_time', 200);

$con = mysql_connect("localhost:3306","root","710100");

if (!$con)

{

die('could not connect: ' . mysql_error());

}

else{

mysql_select_db("test",$con);

$sqla = "select * from index_test_a where title = 'title_4999';";

$sqlb = "select * from index_test_b where  title = 'title_4999';";

$starttimea = microtime();

$result = mysql_query($sqla) or   die( "invalid   query:   "   .   mysql_error());

$endtimea = microtime();

echo "a表查询所有记录所用时间:".(($endtimea-$starttimea)*1000)."毫秒";

echo "
";

$starttimeb = microtime();

$result = mysql_query($sqlb) or   die( "invalid   query:   "   .   mysql_error());

$endtimeb = microtime();

echo "b表查询所有记录所用时间:".(($endtimeb-$starttimeb)*1000)."毫秒";

mysql_close($con); // by www.jbxue.com

}

?>

执行结果如下:

a表查询所有记录所用时间:0.624毫秒

b表查询所有记录所用时间:44.484毫秒

可以看到仅仅10000条记录的查找差别,时间已经相差了几十倍,因此对于经常查询的字段,索引是十分必要的。相应的,如果我们查询没有做索引的字段,那么是没有区别的,将以上的sql语句改为:

复制代码 代码示例:

$sqla = "select * from index_test_a where content = 'content_4999';";

$sqlb = "select * from index_test_b where  content = 'content_4999';";

结果如下:

a表查询所有记录所用时间:23.848毫秒

b表查询所有记录所用时间:24.155毫秒

1.2、测试like查询

在我们项目中,如果数据量大,则不推荐like查询,因为其查询效率比较低,但是对于索引字段来说,like能命中吗?

可以将sql语句改成如下所示:

复制代码 代码示例:

$sqla = "select * from index_test_a where title like '4999%'";

$sqlb = "select * from index_test_b where title like '4999%'";

测试结果:

a表查询所有记录所用时间:0.488毫秒

b表查询所有记录所用时间:25.281毫秒

可以看到对于模糊查询来说,如果是前缀匹配,则会命中索引,但是如果我们将sql改为后缀匹配或者任意匹配,那么二者所消耗的查询时间是一致的:

复制代码 代码示例:

$sqla = "select * from index_test_a where title like '%4999'";

$sqlb = "select * from index_test_b where title like '%4999'";

$sqla = "select * from index_test_a where title like '%4999'";

$sqlb = "select * from index_test_b where title like '%4999'";

a表查询所有记录所用时间:44.742毫秒

b表查询所有记录所用时间:45.752毫秒

即二者都没有命中索引。

1.3、测试or语句,将sql改为如下所示:

复制代码 代码示例:

$sqla = "select * from index_test_a where  content='content_4999' or title='title_4999';";

$sqlb = "select * from index_test_b where  content='content_4999' or title='title_4999';";

测试结果如下:

a表查询所有记录所用时间:49.904毫秒

b表查询所有记录所用时间:50.131毫秒

继续将sql改为如下:

复制代码 代码示例:

$sqla = "select * from index_test_a where  id=4999  or title='title_4999';";

$sqlb = "select * from index_test_b where  id=4999  or title='title_4999';";

测试结果如下:

a表查询所有记录所用时间:0.86毫秒

b表查询所有记录所用时间:47.318毫秒

从上面的结果可以看到,当or中有一个字段没有索引的时候,那么将不会命中索引;反之,如果or运算的所有字段均做了索引,那么是可以命中的。

1.4、测试in,将sql语句继续改为如下所示:

复制代码 代码示例:

$sqla = "select title from index_test_a  where title in ('title_4999','title_5000');";

$sqlb = "select title from index_test_b  where title in ('title_4999','title_5000');";

测试结果为:

a表查询所有记录所用时间:0.817毫秒

b表查询所有记录所用时间:24.234毫秒

可见对于索引字段,in也是可以命中索引的。

1.5、测试,between等,将sql改为如下所示:

复制代码 代码示例:

$sqla = "select title from index_test_a  where num < 999;";

$sqlb = "select title from index_test_b  where num < 999;";

测试结果如下:

a表查询所有记录所用时间:11.469毫秒

b表查询所有记录所用时间:21.728毫秒

可见二者差别不是很大,因此是没有命中索引的。

1.6、对于mysql函数,索引的命中,将sql改为如下所示:

复制代码 代码示例:

$sqla = "select num from index_test_a  where char(num) in ('999','9999');";

$sqlb = "select num from index_test_b  where  char(num) in ('999','9999');";

得到的结果如下所示:

a表查询所有记录所用时间:11.322毫秒

b表查询所有记录所用时间:12.429毫秒

所以如果在条件中使用函数,那么索引将会失效。

2、组合索引

组合索引包括对多个列的索引,而不是多个单列索引的组合,将表a中的所以改成(title,num)的组合索引,进行以下测试:

2.1、or测试

将sql语句改成如下所示:

复制代码 代码示例:

$sqla = "select * from index_test_a where  num=4999  or title='title_4999';";

$sqlb = "select * from index_test_b where  num=4999 or title='title_4999';";

结果如下所示:

a表查询所有记录所用时间:52.535毫秒

b表查询所有记录所用时间:53.031毫秒

这时索引没有命中,索引组合索引的or运算和两个单列索引的or运算是不同的,前者失效而后者依然有效。

2.2、and测试

将sql语句改成如下所示:

复制代码 代码示例:

$sqla = "select * from index_test_a where  num=4999  and title='title_4999';";

$sqlb = "select * from index_test_b where  num=4999 and title='title_4999';";

结果如下所示:

a表查询所有记录所用时间:0.666毫秒

b表查询所有记录所用时间:43.042毫秒

继续改为:

复制代码 代码示例:

$sqla = "select * from index_test_a where  num=4999 ;";

$sqlb = "select * from index_test_b where  num=4999 ;";

得到的结果:

a表查询所有记录所用时间:39.398毫秒

b表查询所有记录所用时间:41.057毫秒

而改成如下sql:

复制代码 代码示例:

$sqla = "select * from index_test_a where  title='title_'4999 ;";

$sqlb = "select * from index_test_b where  title='title_4999' ;";

得到的结果则为:

a表查询所有记录所用时间:0.753毫秒

b表查询所有记录所用时间:48.248毫秒

由以上三组结果可以看出,组合索引是最左前缀匹配的,即条件中要包含第一个索引列,才会命中索引。

3、索引的优缺点

利用索引可以大大加快我们的搜索,但是维护索引需要额外的开销,尤其是当索引较多的时候,大量的数据会很容易带来索引量的膨胀,因此对于频繁要用到的查询,才需要做索引,这样才能以最小的代价获得最大的性能提升。

mysql索引优化应用实例

MySql索引优化注意要点

mysql索引与mysql索引优化查询

Mysql索引优化方法解析

深入理解MySQL索引与优化

mysql索引优化实例分享

mysql索引使用与优化

分享:Mysql索引优化的技巧

mysql性能优化之索引优化

mysql 组合索引 or_mysql索引优化实例(单列索引与组合索引)相关推荐

  1. 覆盖索引与联合索引_Mysql性能优化:为什么要用覆盖索引?

    相信读者看过很多MYSQL索引优化的文章,其中有很多优化的方法,比如最佳左前缀,覆盖索引等方法,但是你真正理解为什么要使用最佳左前缀,为什么使用覆盖索引会提升查询的效率吗? 本篇文章将从MYSQL内部 ...

  2. win7关闭系统索引服务器,如何优化Win7系统之如何关闭索引服务

    Win7如何优化系统? 怎样加快Win7系统优化? Win7系统优化怎么做? 能够使用Windows7操作系统成为了许多电脑用户的一大喜悦之事,相比之前的XP和Vista系统,Windows7系统真的 ...

  3. MySQL~索引设计原则:适合创建索引的11种情况、不适合创建索引的7种情况

    文章目录 数据的准备 适合创建索引 不适合创建索引 数据的准备 #1. 数据的准备CREATE DATABASE atguigudb1;USE atguigudb1;#1.创建学生表和课程表 CREA ...

  4. Mysql数据库优化技术之配置篇、索引篇 ( 必看 必看 转)

    转自:Mysql数据库优化技术之配置篇.索引篇 ( 必看 必看 ) (一)减少数据库访问 对于可以静态化的页面,尽可能静态化 对一个动态页面中可以静态的局部,采用静态化 部分数据可以生成XML,或者文 ...

  5. (2)Mysql索引原理和优化总结

    Mysql设计原理栏目总结 (1)Mysql架构和常用引擎介绍 (2)Mysql索引原理和优化总结 1.索引理解和常见面试题 (1)本质 索引是一种能够高效获取数据的数据结构 索引存放在硬盘上 (2) ...

  6. Mysql 索引原理及优化

    本文内容主要来源于互联网上主流文章,只是按照个人理解稍作整合,后面附有参考链接. 一.摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引 ...

  7. MySQL 如何创建索引?怎么优化?

    2019独角兽企业重金招聘Python工程师标准>>> 索引类似大学图书馆建书目索引,可以提高数据检索的效率,降低数据库的IO成本.MySQL在300万条记录左右性能开始逐渐下降,虽 ...

  8. mysql索引分析_MySQL索引分析和优化

    什么是索引? 索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录.表里面 ...

  9. MySQL索引分析和优化(转)

    MySQL索引分析和优化(转) 索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记 录,直至找到符 ...

最新文章

  1. 独家 | 在浏览器中使用TensorFlow.js和Python构建机器学习模型(附代码)
  2. 练习题知识点整理_C++
  3. c++ string 堆还是栈_5 个刁钻的 String 面试题!你都遇到过哪些?
  4. SpringMVC + Apache POI 实现WEB中Excel下载功能
  5. INTEROP service's ResolveLink operation returned 2 targets for hash, first one
  6. 选择大公司还是小公司
  7. STM32 连续操作flash
  8. Winform读报工具
  9. 关于无线充电的三大标准和四种实现方式的介绍
  10. Android ViewPage使用
  11. 软件定义汽车,OTA技术有多重要?
  12. 英伟达NVIDIA系列显卡GPU CUDA数据对比排行
  13. 6.1. Principles of Usability
  14. 计算机菜单命令后省略号,windows菜单命令项的右边有省略号…表 – 手机爱问
  15. Js网络视频播放器之VideoJsckplayer(直播拉流rtmp、hls)
  16. 前端“智能”静态资源管理 - Onebox - 博客园
  17. 【调剂】福建师范大学海峡创新实验室覃弦接收调剂研究生
  18. 重磅丨云和恩墨zCloud数据库云管平台2.0版本发布
  19. 每年存1.4万,40年后你将有多少钱?算完惊呆了!
  20. 详解 MimbleWimble 协议

热门文章

  1. android 获取phone实例,Android ContentProvider获取手机联系人实例
  2. java对jsonarray去重复_java 去除jsonarray里面jsonarray的重复和合并数据
  3. 查找服务器大文件内容,Linux查找大文件命令,springmvc基础面试题
  4. python 正则表达式 sub_python 正则表达式 re.sub re.subn
  5. js中立即执行函数会预编译吗_面试官:聊聊对Vue.js框架的理解
  6. 使用 保存文件_使用SaveFileDialog调用保存文件对话框
  7. 深度技术Win11 64位最新旗舰版镜像V2021.08
  8. QQ浏览器怎样在首页显示优先推荐的网站
  9. 钉钉怎么查看收到的文件 钉钉查看文件的方法
  10. windows7如何实现屏幕不休眠