组合索引(concatenated index):由多个列构成的索引,如create index idx_emp on emp(col1, col2, col3, ……),则我们称idx_emp索引为组合索引。

在组合索引中有一个重要的概念:引导列(leading column),在上面的例子中,col1列为引导列。当我们进行查询时可以使用”where col1 = ? ”,也可以使用”where col1 = ? and col2 = ?”,这样的限制条件都会使用索引,但是”where col2 = ? ”查询就不会使用该索引。所以限制条件中包含先导列时,该限制条件才会使用该组合索引。

创建2张测试表:

mysql> desc test1;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id | int(11) | NO | | NULL | |
| name | varchar(45) | YES | MUL | NULL | |
| dept | varchar(50) | YES | | NULL | |
| desc | varchar(100) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
4 rows in set (0.00 sec) mysql> desc test2;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| email | varchar(50) | YES | | NULL | |
| address | varchar(50) | YES | | NULL | |
+---------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec) mysql>

通过存储过程模拟一些数据:

delimiter $$
create procedure mock_insert_test1()
BEGIN
DECLARE v int DEFAULT 1;
WHILE v < 800000
DO
INSERT into test1
VALUES(v,CONCAT('name',v),CONCAT('dept',v),NULL);
SET v = v + 1;
END WHILE;
end
$$
delimiter ;
delimiter $$
create procedure mock_insert_test2()
BEGIN
DECLARE v int DEFAULT 1;
WHILE v < 800000
DO
INSERT into test2
VALUES(v,CONCAT('email',v),CONCAT('addr',v));
SET v = v + 1;
END WHILE;
end
$$
delimiter ;

执行存储过程灌一些数据,

mysql> SELECT * from test1 limit 10;
+----+----------+-------+------+
| id | name | dept | desc |
+----+----------+-------+------+
| 1 | duan | yanfa | NULL |
| 2 | zhangsan | renli | NULL |
| 3 | lisi | renli | NULL |
| 1 | name1 | dept1 | NULL |
| 2 | name2 | dept2 | NULL |
| 3 | name3 | dept3 | NULL |
| 4 | name4 | dept4 | NULL |
| 5 | name5 | dept5 | NULL |
| 6 | name6 | dept6 | NULL |
| 7 | name7 | dept7 | NULL |
+----+----------+-------+------+
10 rows in set (0.00 sec) mysql>

引导列是id时,索引是这样的:inx_id_name:id,name

创建索引后,

结果:

引导列是name时,索引是这样的:

结果:

为什么要以name为引导列?因为ID是join列,并且ID列上面没过滤条件,如果以ID列作为引导列,由于没过滤条件那么CBO只能走 index full scan,或者index fast full scan,因为引导列没过滤条件,走不了index range scan,  最多走index skip scan,不过index skip scan代价过高,因为index skip scan要求 引导列选择性很低,但是ID这里选择性很高。

如果name列作为引导列,那么优化器就可以选择index range scan,这样相比index full scan, index fast full scan肯定要少扫描很多leaf block,逻辑读就会相对较少。

其实到这里,是否可以总结一下建立组合索引的原则总结:

  1. 引导列要选择过滤条件的列作为引导列,比如 where a.xxx='xxx' 或者 a.xxx> 或者 a.xxx<
  2. 引导列的选择性越高越好,因为选择性越高,扫描的leaf block就越少,效率就越高  (正确的顺序依赖于使用该索引的查询,并且同时需要考虑如何更好的满足排序和分组的需要。在一个多列B-Tree索引中,索引列的顺序意味着索引首先按照最左列进行排序,其次是第二列。所以,索引可以按照升序或者降序进行扫描,以满足精确符合列顺序的ORDER BY、GROUP BY和DISTINCT等子句的查询需求。对于如何选择索引顺序有一个经验法则:将选择性较高的列放到索引的最前列。)
  3. 尽量把join列放到组合索引最后面

  

Android UI详解之Fragment加载的更多相关文章

  1. 详解QUiLoader 动态加载.ui文件

    http://blog.chinaunix.net/uid-13838881-id-3652523.html 1.适用情况: 动态加载UI文件是指,用 Qt Designer 通过拖拽的方式生产.ui ...

  2. android中的LaunchMode详解----四种加载模式

    Activity有四种加载模式: standard singleTop singleTask singleInstance 配置加载模式的位置在AndroidManifest.xml文件中activi ...

  3. iOS:详解MJRefresh刷新加载更多数据的第三方库

    原文链接:http://www.ios122.com/2015/08/mjrefresh/ 简介 MJRefresh这个第三方库是李明杰老师的杰作,这个框架帮助我们程序员减轻了超级多的麻烦,节约了开发 ...

  4. [转载]jQuery.lazyload详解 - 图片延时加载

    jQuery实现图片延迟加载,不知道是否可以节省带宽呢?有人知道吗? 这究竟只是一个视觉特效还是真的能延迟加载减少服务器的请求呢? <script type="text/javascr ...

  5. 122、详解Glide图片加载库常用方法

    转载:http://blog.csdn.net/android_xiong_st/article/details/53129256 Glide加载网络图片, 显示的还是以前的图片! (最全解决方案!) ...

  6. Android系列之Fragment(一)----Fragment加载到Activity当中

    Android上 的界面展示都是通过Activity实现的,Activity实在是太常用了.但是Activity也有它的局限性,同样的界面在手机上显示可能很好看, 在平板上就未必了,因为平板的屏幕非常 ...

  7. android开发之Fragment加载到一个Activity中

    Fragments 是android3.0以后添加的.主要是为了方便android平板端的开发.方便适应不同大小的屏幕.此代码是为了最简单的Fragment的使用,往一个Activity中添加Frag ...

  8. Android 布局详解

    Android 布局详解 1.重用布局 当一个布局文件被多处使用时,最好<include>标签来重用布局. 例如:workspace_screen.xml的布局文件,在另一个布局文件中被重 ...

  9. Android Notification 详解(一)——基本操作

    Android Notification 详解(一)--基本操作 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Notification 文中如有纰 ...

随机推荐

  1. asp.net后台获取路径的各种方法归纳

    asp.net后台获取路径的各种方法归纳   1.Request.CurrentExecutionFilePath    获取当前请求的虚拟路径,不同于 FilePath,差别在于如果请求已在服务器代 ...

  2. Git教程之管理修改(6)

    Git比其他版本控制系统设计得优秀,因为Git跟踪并管理的是修改,而非文件.你会问,什么是修改?比如你新增了一行,这就是一个修改,删除了一行,也是一个修改,更改了某些字符,也是一个修改,删了一些又加了 ...

  3. Git教程之时光穿梭(3)

    我们已经成功地添加并提交了一个readme.txt文件,现在我们继续修改readme.txt文件,改成如下内容:

  4. 基于Struts2框架实现登录案例 之 使用Struts2标签库简化表单+继承ActionSupport完成输入交验

    一,使用Struts2标签库简化表单 在文章[基于Struts2框架实现登录案例]的基础上,通过使用Struts标签库可以简化登录页面login2.jsp <%@ page language=& ...

  5. highcharts 结合phantomjs纯后台生成图片系列二之php

    上篇文章中介绍了phantomjs的使用场景,方法.本篇文章详细介绍使用php,highcharts 结合phantomjs纯后台生成图片. 一.准备: 下载phantomjs解析插件,从 highc ...

  6. [原]用WebBrowser组件模拟人工运行搜索引擎自动点击搜索结果的实验

    本代码只是业余时间无聊写着试试,用WebBrowser组件模拟人工运行搜索引擎自动点击搜索结果的实验 这是网络中盛传的提高搜索引擎点击率的一种方式,当然属于作弊,不推荐各位使用.另外这种方式的性能不佳 ...

  7. 函数xdes_calc_descriptor_page

    根据偏移量计算出第几个xdes page 0 %16328 = 0 64% 16328 = 64 128 % 16328 = 128 192 % 16328 = 192 /************** ...

  8. bzoj1297: [SCOI2009]迷路

    矩阵. 一个图的邻接矩阵的m次幂相当于 长度恰好为m的路径数.这要求边权为1. 因为边权小于等于9,所以可以把一个点拆成9的点. 拆成的第(i+1)个点向第i个点连边. 如果存在边(u,v,w) 就由 ...

  9. 转:MVC3系列:~Html.BeginForm与Ajax.BeginForm

    Html.BeginForm与Ajax.BeginForm都是MVC架构中的表单元素,它们从字面上可以看到区别,即Html.BeginForm是普通的表单提交,而Ajax.BeginForm是支持异步 ...

  10. Mysql的 时间戳转换 和 c# 的时间戳转换 (以秒来进行转换,非毫秒,主要是mysql不能存毫秒)

    Mysql 时间戳函数 => 从时间 转成 时间戳   UNIX_TIMESTAMP() 获取当前服务器时间的时间戳 UNIX_TIMESTAMP('2013-01-01 12:33:19') ...