热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

复合索引性能问题初探-mysql教程

在《品悟性能优化》一书,4.4.3章节里介绍了复合索引的两个特点:前缀性,可选性。何为前缀性,该书阐述为排除skipscanindex的情况(索引前置列的取不多,如性别),约束条件如果不包含复合索引的第一列,则该复合索引不会被用到;何为可选性,该书阐述为字

在《品悟性能优化》一书,4.4.3章节里介绍了复合索引的两个特点:前缀性,可选性。何为前缀性,该书阐述为排除skip scan index的情况(索引前置列的取不多,如性别),约束条件如果不包含复合索引的第一列,则该复合索引不会被用到;何为可选性,该书阐述为字

在《品悟性能优化》一书,4.4.3章节里介绍了复合索引的两个特点:前缀性,可选性。何为前缀性,该书阐述为排除skip scan index的情况(索引前置列的取值不多,如性别),约束条件如果不包含复合索引的第一列,则该复合索引不会被用到;何为可选性,该书阐述为字段值越多,可选性越强,定位记录越少,查询效率越高。即查询返回记录少的列应该放在复合索引的前面。

而在《收获不止oracle》一书,5.2.1.9章节里也介绍了复合索引的两个特点:①在等值查询的情况下,复合索引的列无论那一列在前,性能都一样。②复合索引的两列,当一列是范围查询,一列是等值查询的情况下,等值查询列在前,范围查询列在后,这样的索引才是高效的。

根据上述对复合索引两位作者的不同见解之处,我们通过测试,辨别下实事的真相。测试环境是11.2.0.3单实例,oracle linux 5.4

SQL> create table t as select * from dba_objects;

Table created.

SQL> select count(*) from t;

COUNT(*)
----------
109971

SQL> select count(distinct object_type) from t;

COUNT(DISTINCTOBJECT_TYPE)
--------------------------
45

SQL> select count(distinct object_id) from t;

COUNT(DISTINCTOBJECT_ID)
------------------------
109971

SQL> create index ind_t_obj_id on t(object_id,object_type);

Index created.

SQL> create index ind_t_obj_ty on t(object_type,object_id);

Index created.

SQL> select /*+ index(t,ind_t_obj_ty) */ * from T where object_id=5585 and object_type='TABLE';

Execution Plan
----------------------------------------------------------
Plan hash value: 2583045626

--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 11 | 2277 | 4 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| T | 11 | 2277 | 4 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IND_T_OBJ_TY | 2 | | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - access("OBJECT_TYPE"='TABLE' AND "OBJECT_ID"=5585)

Note
-----
- dynamic sampling used for this statement (level=2)

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
5 consistent gets
0 physical reads
0 redo size
1622 bytes sent via SQL*Net to client
520 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed

SQL> select /*+ index(t,ind_t_obj_id) */ * from T where object_id=5585 and object_type='TABLE';

Execution Plan
----------------------------------------------------------
Plan hash value: 607336433

--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 11 | 2277 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| T | 11 | 2277 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IND_T_OBJ_ID | 2 | | 1 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - access("OBJECT_ID"=5585 AND "OBJECT_TYPE"='TABLE')

Note
-----
- dynamic sampling used for this statement (level=2)

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
4 consistent gets
0 physical reads
0 redo size
1622 bytes sent via SQL*Net to client
520 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed

我们这里看到等值查询结果是不一样的,证实了《品悟》一书的可选性是正确的。

SQL> select /*&#43; index(t,ind_t_obj_ty) */ * from T where object_id > 20 and object_id <2000 and object_type='TABLE';

488 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 2583045626

--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 912 | 184K| 49 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| T | 912 | 184K| 49 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IND_T_OBJ_TY | 912 | | 6 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - access("OBJECT_TYPE"='TABLE' AND "OBJECT_ID">20 AND "OBJECT_ID"<2000)

Note
-----
- dynamic sampling used for this statement (level=2)

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
85 consistent gets
0 physical reads
0 redo size
51220 bytes sent via SQL*Net to client
872 bytes received via SQL*Net from client
34 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
488 rows processed

SQL> select /*&#43; index(t,ind_t_obj_id) */ * from T where object_id > 20 and object_id <2000 and object_type='TABLE';

488 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 607336433

--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 912 | 184K| 11 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| T | 912 | 184K| 11 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IND_T_OBJ_ID | 9 | | 10 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - access("OBJECT_ID">20 AND "OBJECT_TYPE"='TABLE' AND "OBJECT_ID"<2000)
filter("OBJECT_TYPE"='TABLE')

Note
-----
- dynamic sampling used for this statement (level=2)

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
87 consistent gets
0 physical reads
0 redo size
51220 bytes sent via SQL*Net to client
872 bytes received via SQL*Net from client
34 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
488 rows processed

结果,不言而喻。以上两个sql在不用hint的时候,CBO都会自动选择走IND_T_OBJ_ID。所以,《收获不止oracle》一书的结论有待商榷(如果不是我测试有问题的话)。
推荐阅读
  • 本文档提供了详细的MySQL安装步骤,包括解压安装文件、选择安装类型、配置MySQL服务以及设置管理员密码等关键环节,帮助用户顺利完成MySQL的安装。 ... [详细]
  • 对于初次购买阿里云服务器的新手用户来说,如何高效地利用服务器资源并成功部署网站是一个重要的课题。本文将详细指导您完成从购买服务器到网站上线的六个关键步骤。 ... [详细]
  • 本文介绍了多种将多行数据合并为单行的方法,包括使用动态SQL、函数、CTE等技术,适用于不同的SQL Server版本。 ... [详细]
  • SQLite是一种轻量级的关系型数据库管理系统,尽管体积小巧,却能支持高达2TB的数据库容量,每个数据库以单个文件形式存储。本文将详细介绍SQLite在Android开发中的应用,包括其数据存储机制、事务处理方式及数据类型的动态特性。 ... [详细]
  • Navicat Premium中MySQL用户管理:创建新用户及高级设置
    本文作为Navicat Premium用户管理系列的第二部分,主要介绍如何创建新的MySQL用户,包括设置基本账户信息、密码策略、账户限制以及SSL配置等。 ... [详细]
  • 帝国cms各数据表有什么用
    CMS教程|帝国CMS帝国cmsCMS教程-帝国CMS精易编程助手源码,ubuntu桥接设置,500错误是tomcat吗,爬虫c原理,php会话包括什么,营销seo关键词优化一般多 ... [详细]
  • 本文详细探讨了 HAProxy 的基本概念及其与 LVS(Linux Virtual Server)的比较,特别是在内核空间与用户空间的工作差异。文章还深入介绍了 HAProxy 独有的数据结构——弹性二叉树,以及其在高并发场景下的表现。 ... [详细]
  • 本文介绍了多种Eclipse插件,包括XML Schema Infoset Model (XSD)、Graphical Editing Framework (GEF)、Eclipse Modeling Framework (EMF)等,涵盖了从Web开发到图形界面编辑的多个方面。 ... [详细]
  • 本文介绍如何在SQL Server中利用WITH子句和窗口函数ROW_NUMBER()来查询每个类型下的最新数据行。示例包括表结构、数据插入以及最终的查询语句。 ... [详细]
  • 深入浅出:Hadoop架构详解
    Hadoop作为大数据处理的核心技术,包含了一系列组件如HDFS(分布式文件系统)、YARN(资源管理框架)和MapReduce(并行计算模型)。本文将通过实例解析Hadoop的工作原理及其优势。 ... [详细]
  • 本文介绍了一种在Oracle 19c数据库中恢复被误删除表数据的方法,包括启用行移动功能和使用闪回技术,适用于表结构未被删除但数据丢失的情况。 ... [详细]
  • 本文详细介绍了在 Windows 7 上安装和配置 PHP 5.4 的 Memcached 分布式缓存系统的方法,旨在减少数据库的频繁访问,提高应用程序的响应速度。 ... [详细]
  • 数据库环境:SQLSERVER2005  有一个test表,其表结构及数据如下图1。其中,id是主键,mid是当前节点,pid是父节点。要求:查出每个节点的根节点,如图2所示。 ... [详细]
  • 本文介绍了如何在Laravel框架中使用Select方法进行数据库查询,特别是当需要根据传入的分类ID查询相关产品时的正确做法和注意事项。 ... [详细]
  • 深入解析轻量级数据库 SQL Server Express LocalDB
    本文详细介绍了 SQL Server Express LocalDB,这是一种轻量级的本地 T-SQL 数据库解决方案,特别适合开发环境使用。文章还探讨了 LocalDB 与其他轻量级数据库的对比,并提供了安装和连接 LocalDB 的步骤。 ... [详细]
author-avatar
意淫图
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有