由索引引出简单实验几例 ***********************************************声明************************************************ 原创作品,出自 深蓝的blog 博客,欢迎转载,转载时请务必注明出处(http://blog.csdn.net/huangyanlong)。 表述有错误之处

由索引引出简单实验几例

***********************************************声明************************************************

原创作品,出自 “深蓝的blog” 博客,欢迎转载,转载时请务必注明出处(http://blog.csdn.net/huangyanlong)。

表述有错误之处,请您留言,不胜感激。

提醒:点击目录,更有助于您的查看。

*****************************************************************************************************

对之前的小例子重新归纳了一下,希望可以帮助对索引有进一步的理解。

【例1】数据量小不需建索引

//如果表的数据量很少,全表扫描和走索引成本相差很小,使用索引是不是就没有必要了。

实验操作:

SQL> SELECT ENAME,JOB,SAL FROM SCOTT.EMP;

//先找到一张小表以作实验,查看表中信息,只有14行

ENAME JOB SAL

---------- --------- ------

SMITH CLERK 800

ALLEN SALESMAN 1600

WARD SALESMAN 1250

JONES MANAGER 2975

MARTIN SALESMAN 1250

BLAKE MANAGER 2850

CLARK MANAGER 2450

SCOTT ANALYST 3000

KING PRESIDENT 5000

TURNER SALESMAN 1500

ADAMS CLERK 1100

JAMES CLERK 950

FORD ANALYST 3000

MILLER CLERK 1300

已选择14行。

SQL> SET AUTOTRACE ON

SQL> SET AUTOTRACE TRACEONLY

SQL> SELECT * FROM SCOTT.EMP WHERE ENAME='JAMES';

//全表扫描查找JAMES的信息

--------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

--------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 38 | 3 (0)| 00:00:01 |

|* 1 | TABLE ACCESS FULL| EMP | 1 | 38 | 3 (0)| 00:00:01 |

--------------------------------------------------------------------------

SQL> CREATE INDEX IND_EMP_ENAME ON SCOTT.EMP(ENAME);

//为ENAME列建索引

SQL> SELECT * FROM SCOTT.EMP WHERE ENAME='JAMES';

//走列索引查找JAMES的信息

--------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

-------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 38 | 2 (0)| 00:00:01 |

| 1 | TABLE ACCESS BY INDEX ROWID| EMP | 1 | 38 | 2 (0)| 00:00:01 |

|* 2 | INDEX RANGE SCAN | IND_EMP_ENAME | 1 | | 1 (0)| 00:00:01 |

--------------------------------------------------------------------------------

//全表扫描成本是3%,走索引成本是2%

//从以上实验发现,在表的数据量很小的情况下,全表扫描和走索引成本上相差不大。

【例2】全表扫描IO成本低于使用索引情况

**************************************************************************

举一个例子,不恰当的使用索引,比用全表扫描的的IO成本更加高。

**************************************************************************

解答:

思路:创建一组rowid是散落在多个表数据块中的索引,这样由于索引列数据的分布情况和索引中的顺序差异很大,致使通过全表扫表比走索引更能降低IO的使用成本。

操作如下:

SQL> CREATE TABLE TAB_HYL AS SELECT * FROM DBA_OBJECTS;

//创建了一个TAB_HYL表以作实验

SQL> ANALYZE TABLE TAB_HYL COMPUTE STATISTICS;

//分析这张TAB_HYL实验表

SQL> SELECT NUM_ROWS,BLOCKS FROM USER_TABLES WHERE TABLE_NAME ='TAB_HYL';

//查找出实验表上的行数、块数

NUM_ROWS BLOCKS

---------- ----------

72606 1033

SQL> SELECT 72606/1033 FROM DUAL;

//计算平均每个块中的行数为70行

72606/1033

----------

70.286544

SQL> DROP TABLE TAB_HYL PURGE;

//删除这张表,这张表就是为了计算出每块所占的行数,从而对其进行构建完成实验

SQL> CREATE TABLE TAB_HYL AS SELECT * FROM DBA_OBJECTS WHERE ROWNUM<=70;

//重新创建实验表让它装入70行形成第一个块

SQL> INSERT INTO TAB_HYL SELECT * FROM TAB_HYL;

//复制相同的70行插到实验表中,即实验表中共有140行数据,两个块

SQL> /

//再次执行相同操作,但此时基准的实验表为140行,因此第三次插入了140行数据,即现在实验表有280行数据

SQL> /

//按照上面的方法以下连续创建,形成多个块,让每个块中都有相同的键值而形成一组实验用的ROWID

SQL> /

SQL> /

SQL> /

SQL> /

SQL> COMMIT;

SQL> CREATE INDEX IND_H1 ON TAB_HYL(OBJECT_ID);

//创建实验表中OBJECT_ID列的索引,之后通过该列值进行查询,来说明查询的成本

SQL> ANALYZE TABLE TAB_HYL COMPUTE STATISTICS; //分析一下实验表

SQL> SELECT NUM_ROWS,BLOCKS FROM USER_TABLES WHERE TABLE_NAME ='TAB_HYL';

//查看一下此时实验表的行数、块数已经达到实验准备条件,可以开始试验了

NUM_ROWS BLOCKS

---------- ----------

8960 103

SQL> SET AUTOTRACE ON

SQL> SET AUTOTRACE TRACEONLY

//设定跟踪

SQL> SELECT * FROM TAB_HYL WHERE OBJECT_ID=70;

//通过上面创建了索引的列来查找,得到下面的分析结果,记住cpu的成本为30,并且数据库自动完成的是走全表扫描,说明数据库已经判断出什么方式查询,成本更低了。

----------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

----------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 128 | 10112 | 30 (0)| 00:00:01 |

|* 1 | TABLE ACCESS FULL| TAB_HYL | 128 | 10112 | 30 (0)| 00:00:01 |

----------------------------------------------------------------------

//之后我们人为让查询走索引再看一下分析结果。

SQL> SELECT /*+INDEX(TAB_HYL IND_H1)*/ * FROM TAB_HYL WHERE OBJECT_ID=70;

//强制查询走索引,输出一下结果,看到成本是102,要远高于全表扫描的成本(全表扫描是30,见上表)。

----------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time

----------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 128 | 10112 | 102(0)| 00:00:02 |

| 1 | TABLE ACCESS BY INDEX ROWID| TAB_HYL | 128 | 10112 | 102(0)| 00:00:02 |

|* 2 | INDEX RANGE SCAN | IND_H1 | 128 | | 1(0)| 00:00:01 |

----------------------------------------------------------------------

通过以上实验说明,当索引列数据的分布情况和索引中的顺序差异很大这种情况出现时,做索引范围扫描效率偏低。

【例3】构造表时集簇因子数分别为接近块数、接近行数

**************************************************************************

建两张表,各建一个索引。要求A表的索引集簇因子接近表块数,B表的索引集簇因子接近表行数。

**************************************************************************

(一)、创建A表:索引集簇因子接近表块数

操作:

SQL> CREATE TABLE TAB_HYL AS SELECT * FROM DBA_OBJECTS;

//先创建了一个TAB_HYL表以作实验源表,为了通过这个表分析出表中一个块所占的行数

SQL> ANALYZE TABLE TAB_HYL COMPUTE STATISTICS;

//分析这张TAB_HYL实验表

SQL> SELECT NUM_ROWS,BLOCKS FROM USER_TABLES WHERE TABLE_NAME ='TAB_HYL';

//查找出实验表上的行数、块数

NUM_ROWS BLOCKS

---------- ----------

72606 1033

SQL> SELECT 72606/1033 FROM DUAL;

//计算平均每个块中的行数为70行

72606/1033

----------

70.286544

SQL> DROP TABLE TAB_HYL PURGE;

//删除这张表

SQL> CREATE TABLE TAB_HYL AS SELECT * FROM DBA_OBJECTS WHERE ROWNUM<=70;

//重新创建实验表让它装入70行形成第一个块

SQL> INSERT INTO TAB_HYL SELECT * FROM TAB_HYL;

//复制相同的70行插到实验表中,即实验表中共有140行数据,两个块

SQL> /

//再次执行相同操作,但此时基准的实验表为140行,因此第三次插入了140行数据,即现在实验表有280行数据

SQL> /

//按照上面的方法以下连续创建,这是为了构造实验表的集簇因子

SQL> /

SQL> /

SQL> /

SQL> /

SQL> COMMIT;

SQL> CREATE TABLE TAB_A AS SELECT * FROM TAB_HYL ORDER BY OBJECT_ID;

//根据实验表创建出表A,表A是通过OBJECT_ID排序的,因此就得到了键值相同的分布较集中的块

SQL> CREATE INDEX IND_H1 ON TAB_A(OBJECT_ID);

//创建A表中OBJECT_ID列的索引

SQL> ANALYZE TABLE TAB_A COMPUTE STATISTICS;

//分析一下A表

SQL> SELECT NUM_ROWS,BLOCKS FROM USER_TABLES WHERE TABLE_NAME = 'TAB_A';

NUM_ROWS BLOCKS

---------- ----------

8960 102

SQL> SELECT BLEVEL,LEAF_BLOCKS,DISTINCT_KEYS,AVG_LEAF_BLOCKS_PER_KEY,CLUSTERING_FACTOR

2 FROM USER_INDEXES

3 WHERE INDEX_NAME = 'IND_H1';

//查看A表索引列的b-tree级别、叶的块数、不同的key值、平均每个key所占的叶块的数量、聚集的因子

BLEVEL LEAF_BLOCKS DISTINCT_KEYS AVG_LEAF_BLOCKS_PER_KEY CLUSTERING_FACTOR

------- ----------- ------------- ----------------------- -----------------

1 18 70 1 102

//得到了A表索引列的集簇因子数(102)与上面的A表的块数(102)是相同的。

(二)、创建B表:索引集簇因子接近表行数

操作:

SQL> CREATE TABLE TAB_HYL AS SELECT * FROM DBA_OBJECTS;//创建了一个实验表以作实验

SQL> ANALYZE TABLE TAB_HYL COMPUTE STATISTICS;//分析这张TAB_HYL实验表

SQL> SELECT NUM_ROWS,BLOCKS FROM USER_TABLES WHERE TABLE_NAME ='TAB_HYL';//查找出实验表上的行数、块数

NUM_ROWS BLOCKS

---------- ----------

72606 1033

SQL> SELECT 72606/1033 FROM DUAL;//计算平均每个块中的行数为70行

72606/1033

----------

70.286544

SQL> DROP TABLE TAB_HYL PURGE;//删除这张表

SQL> CREATE TABLE TAB_B AS SELECT * FROM DBA_OBJECTS WHERE ROWNUM<=70;//创建B表让它装入70行形成第一个块

SQL> INSERT INTO TAB_B SELECT * FROM TAB_B;//复制相同的70行插到B表中,即B表中共有140行数据,两个块

SQL> / //再次执行相同操作,但此时基准的B表为140行,因此第三次插入了140行数据,即现在B表有280行数据

SQL> / //按照上面的方法以下连续创建,这是为了构造B表的集簇因子

SQL> /

SQL> /

SQL> /

SQL> /

SQL> COMMIT;

SQL> CREATE INDEX IND_H2 ON TAB_B(OBJECT_ID);//创建B表中OBJECT_ID列的索引

SQL> ANALYZE TABLE TAB_B COMPUTE STATISTICS; //分析一下B表

SQL> SELECT NUM_ROWS,BLOCKS FROM USER_TABLES WHERE TABLE_NAME ='TAB_B';//查看一下此时B表的行数、块数

NUM_ROWS BLOCKS

---------- ----------

8960 103

SQL> SELECT BLEVEL,LEAF_BLOCKS,DISTINCT_KEYS,AVG_LEAF_BLOCKS_PER_KEY,CLUSTERING_FACTOR

2 FROM USER_INDEXES

3 WHERE INDEX_NAME = 'IND_H2';

//查看B表索引列的b-tree级别、叶的块数、不同的key值、平均每个key所占的叶块的数量、集簇因子

BLEVEL LEAF_BLOCKS DISTINCT_KEYS AVG_LEAF_BLOCKS_PER_KEY CLUSTERING_FACTOR

------- ----------- ------------- ----------------------- -----------------

1 18 70 1 7070

//B表索引列的集簇因子(7070)和B表中的行数(8960)相对接近.

【例4】有关索引监控

**************************************************************************

对一张表的索引开监控,看是否有使用到。

**************************************************************************

会话A:

SQL> ALTER INDEX IND_H1 MONITORING USAGE;

//对上面练习中用到的IND_H1索引开监控

SQL> SELECT * FROM V$OBJECT_USAGE;

//通过查看V$OBJECT_USAGE视图查看对IND_H1索引的监控信息,MON为YES代表已经开监控了,当前没有人用到

INDEX_NAME TABLE_NAME MON USE START_MONITORING END_MONITORING

------------------- ---------------------- --- --- ------------------- -------------------

IND_H1 TAB_A YES NO 03/18/2014 16:54:29

会话B:

SQL> SET AUTOTRACE ON;

//开监控,确认下面的操作是走索引的

SQL> SELECT * FROM TAB_A WHERE OBJECT_ID=70;

//使用带索引列查询,分析结果如下

--------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 128 | 10112 | 3 (0)| 00:0

0:01 |

| 1 | TABLE ACCESS BY INDEX ROWID| TAB_A | 128 | 10112 | 3 (0)| 00:0

0:01 |

|* 2 | INDEX RANGE SCAN | IND_H1 | 128 | | 1 (0)| 00:0

0:01 |

--------------------------------------------------------------------------------

会话A:

SQL> SELECT * FROM V$OBJECT_USAGE;

//再次通过V$OBJECT_USAGE视图查看对IND_H1索引的监控信息,MON为YES代表已经开监控了,USE为YES代表当前有人在使用

INDEX_NAME TABLE_NAME MON USE START_MONITORING END_MONITORING

------------------- ---------------------- --- --- ------------------- -------------------

IND_H1 TAB_A YES YES 03/18/2014 16:54:29

***********************************************声明************************************************

原创作品,出自 “深蓝的blog” 博客,欢迎转载,转载时请务必注明出处(http://blog.csdn.net/huangyanlong)。

表述有错误之处,请您留言,不胜感激。

提醒:点击目录,更有助于您的查看。

*****************************************************************************************************

本文原创发布php中文网,转载请注明出处,感谢您的尊重!

mysql索引 实验_“索引”实验小例相关推荐

  1. sql server修改索引名称_索引基本知识和索引优化

    " 索引基本知识*哈希索引*组合索引*聚簇索引与非聚簇索引*覆盖索引*索引优化*索引监控*优化案例" 索引这个东西,个人的感觉是:平时大家都不怎么重视他,感觉哪个查询慢了就对那个列 ...

  2. like左匹配索引失效_索引失效的情况

    索引对于MySQL而言,是非常重要的篇章.索引知识点也巨多,要想掌握透彻,需要逐个知识点一一击破,今天来先来聊聊哪些情况下会导致索引失效. 图片总结版 全值匹配(索引最佳) explain selec ...

  3. 机器人焊枪动作与编程实验_机器人实验指导用书.doc

    机器人实验指导用书 <工业机器人>课程实验指导书 刘极峰 肖增文 邵秋萍 郝飞 编 机电工程实验中心机器人实验室 目 录 实验一 慧鱼机器人模型组装综合实验1 附件1 实验一 慧鱼机器人模 ...

  4. mysql 创建外键索引吗_索引-MySQL无法创建外键约束

    我在为mysql数据库中的现有表创建外键时遇到一些问题. 我有experiment表: +-------------+------------------+------+-----+--------- ...

  5. eigrp配置实验_【实验】思科与华为的差别——路由的优选

    相信大家学习思科或者华为的网络技术时,静态路由和动态路由协议都是我们学习的重中之重. 比如常用的静态路由和OSPF路由协议相信大家应该不陌生吧,那咱们今天就静态路由和OSPF的优选谈谈. 先谈思科,在 ...

  6. java 实验十 数据库实验_数据库实验十[荟萃内容]

    <数据库实验十[荟萃内容]>由会员分享,可在线阅读,更多相关<数据库实验十[荟萃内容](9页珍藏版)>请在人人文库网上搜索. 1.北京建筑大学理学院 信息与计算科学专业 实验报 ...

  7. shell 获取 mysql 行数_一个Shell小脚本精准统计Mysql每张表的行数实现

    前言 对于开发或者运维人员来说,Mysql数据库每张表的数量肯定是要了解下,有助于我们清理无用数据或者了解哪张表比较占用空间. 另外多次统计表的行数,还能发现Mysql表的增量情况,能够预测表未来会有 ...

  8. 关联的两个字段度需要建立索引吗_索引那些事儿

    最近的工作中进行了几个SQL优化,对索引也有了一些新的认识. 什么是索引? 百度百科是这么说的: 在关系数据库中,索引是一种单独的.物理的对数据库表中一列或多列的值进行排序的一种存储结构,它是某个表中 ...

  9. python 物理实验_物理实验

    前沿导读王敬雪;涂浩然;闫羽;苏峰;杜晓波; 介绍了机械化学的定义.发展历史.特点.机理和应用,重点介绍了近期发现的稀土过渡族合金在正庚烷中球磨的过程中,正庚烷分解产生氢气和碳,以及氢气与稀土过渡族合 ...

最新文章

  1. 以服务的方式提供站点基础功能支持
  2. Oracle 原理:临时表空间的操作方式
  3. Java 9对可选的补充
  4. Innodb之监控Buffer pool Load progress
  5. 学了python能干啥举例-Python主要用来做什么?
  6. 移动Web界面样式-CSS3
  7. MVC 下拉列表三级联动
  8. BT没死!305个国外BT资源聚合站点大全
  9. 2010年全国职称计算机考试专用教程——AutoCAD 2004制图软件 (含光盘下载)
  10. android 改机型玩王者,安卓手机改机型华为nova 8 Pro体验《王者荣耀》90帧超高帧率模式...
  11. linux 物理内存 查看,Linux查看物理内存信息
  12. 石墨烯在生物医学上应用的研究进展_石墨烯在润滑油中的应用
  13. 高并发 高负载 网站系统架构
  14. java猫抓老鼠_用猫抓老鼠的实例理解java中面向对象的编程与类和对象以及方法的概念...
  15. C 语言为什么不会过时?
  16. 微信自动回复小程序(有手就行)
  17. cf 985E Pencils and Boxes
  18. 新唐N76e003 单片机程序分析
  19. 《Pro SQL Server Internals, 2nd edition》CHAPTER 3 Statistics
  20. STM32F103单片机解密资料

热门文章

  1. 九毛九集团java_JAVA数组课后作业
  2. 织梦dede:channelartlist调用排除指定typeid栏目
  3. Java运算符——通过示例学习Java编程(6)
  4. AOP之proceedingjoinpoint和joinpoint区别(获取各对象备忘)、动态代理机制及获取原理代理对象、获取Mybatis Mapper接口原始对象...
  5. (数论)逆元的线性算法
  6. MANIFEST.MF的用途(转载)
  7. Redis命令参考【EXPIRE】
  8. thinkphp 相关
  9. python执行循环内存变大_python – 为什么我的循环在每次迭代时需要更多内存?...
  10. NameNode之数据块管理