在9i,我们知道count(*)的时候,如果表上有pk,那count(*) 一定会走pk的。count(column) ,如果column指定not
null,那count(column)
可以走上索引(通过试验证明,必须还要加上index提示才能走上索引)。但如果列上有空值,不管如何加提示,都走不上列上的索引(组合索引的非引导列除外)
count是否应该走索引,主要取决于count是否应该把空值算进来。所以,
count(column) ,不管字段是否有null,都可以走索引。进而我们可以推论,如果表上存在一not
null的字段,而且这个字段上有索引,表上即使没有pk,count(*)也可以通过扫描整个索引完成计数。在11g里面,oracle改进了策略。测试如下:
在9i里面,无论如何写提示,都没办法走上COL_IND索引的。因为col1字段允许为null(虽然实际数据没有null值,分析统计信息也是没用的)
此时count(*),全表扫描:
如我们推论的那样,即使没有PK,存在一个not
null的字段,且字段上有索引。count(*)会使用表完成计数。
但如果一个无pk的表上出现多个not
null且有索引的字段,那count(*)走哪个索引呢?我们很自然的想到了成本。哪个成本小,走哪个。测试一下:
1 consistent gets
>create table test (col1 varchar2(32),col2 varchar2(32));
Table created
>insert into test
2 select id,member_id
3 from b
where rownum<=10;
>select * from test;
COL1 COL2
——————————– ——————————–
477234 shenzhenxiechang
291004
shenzhoutouzi
345045 hgyingzi
212170 ntdongyi
493284
ntfashion
200282 rebecca123
1199257 szjinshuipos
629740 nttg
1512060
rich228
772466 nxyk
>create index col_ind on test (col1);
>create index co2_ind on test
(col2);
Index created.
Index created.
>select count(col1) from
test;
COUNT(COL1)
———–
10
1 row selected.
Execution Plan
———————————————————-
Plan hash value: 4154769577
—————————————————————————-
| Id | Operation | Name | Rows | Bytes | Cost
(%CPU)| Time |
—————————————————————————-
| 0 | SELECT STATEMENT | | 1 | 7
| 1 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 7 | | |
| 2 | INDEX FULL
SCAN| COL_IND | 10 | 70 | 1 (0)| 00:00:01 |
—————————————————————————-
>select count(*) from test;
COUNT(*)
———-
10
1 row selected.
Execution Plan
———————————————————-
Plan hash value: 1950795681
——————————————————————-
| Id | Operation | Name | Rows | Cost (%CPU)| Time
|
——————————————————————-
| 0 | SELECT STATEMENT | | 1 | 18 (0)| 00:00:01
|
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| TEST | 10 | 18
(0)| 00:00:01 |
——————————————————————-
把其中一个字段改为not null:
>alter table test modify(col2 not null);
Table altered.
>desc test
Name Null?
Type
———————————————————————————– ——– ——————————————————–
COL1
VARCHAR2(32)
COL2 NOT NULL VARCHAR2(32)
>select count(*) from test;
COUNT(*)
———-
10
1 row selected.
Execution Plan
———————————————————-
Plan hash value: 73288374
——————————————————————–
| Id | Operation | Name | Rows | Cost (%CPU)| Time
|
——————————————————————–
| 0 | SELECT STATEMENT | | 1 | 1 (0)| 00:00:01
|
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FULL SCAN| CO2_IND | 10 | 1
(0)| 00:00:01 |
——————————————————————–
>update test set col2=col2||lpad(col2,3500,’a');
10 rows updated.
>analyze table test compute statistics for all
indexes;
Table analyzed.
update字段前的索引统计信息:
name NUM_ROWS distinct LEAF_BLOCKS cf
level alfbpkey
—————————— ———- ———- ———– ———- ———- ———-
CO2_IND 10 10 1 1
0 1
COL_IND 10 10 1 1 0 1
update之后的:
name NUM_ROWS distinct LEAF_BLOCKS
cf level alfbpkey
—————————— ———- ———- ———– ———- ———- ———-
CO2_IND 10 10 5
1 1 1
COL_IND 10 10 1 1 0 1
>select count(*) from test;
COUNT(*)
———-
10
1 row selected.
Execution Plan
———————————————————-
Plan hash value: 4154769577
——————————————————————–
| Id | Operation | Name | Rows | Cost (%CPU)| Time
|
——————————————————————–
| 0 | SELECT STATEMENT | | 1 | 1 (0)| 00:00:01
|
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FULL SCAN| COL_IND | 10 | 1
(0)| 00:00:01 |
——————————————————————–
CBO还是根据访问索引的成本选择了成本小的索引进行访问。如果通过index提示,走CO2_IND.
6 consistent
gets这个时候,pk对于count(*)来说完全无意义了。完全通过成本决定走哪个索引
注:由于手里没10g的测试环境,不知道这个改进是否在10g就已经有了。
>alter table test add constraint test_pk primary key (col2);
Table altered.
>>select count(*) from test;
COUNT(*)
———-
10
1 row selected.
Execution Plan
———————————————————-
Plan hash value: 4154769577
——————————————————————–
| Id | Operation | Name | Rows | Cost (%CPU)| Time
|
——————————————————————–
| 0 | SELECT STATEMENT | | 1 | 1 (0)| 00:00:01
|
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FULL SCAN| COL_IND | 10 | 1
(0)| 00:00:01 |
分享到:
相关推荐
第一部分 ORACLE系统优化基本知识 23 第1章 ORACLE结构回顾 23 §1.1 Oracle数据库结构 23 §1.1.1 Oracle数据字典 23 §1.1.2 表空间与数据文件 24 §1.1.3 Oracle实例(Instance) 24 §1.2 Oracle文件 26 §1.2.1...
一个简单的实用程序 PL/SQL 包,允许对 Oracle 中的合并操作插入/更新/删除的行进行计数。 包的需要 Oracle不提供获取行数的功能。 插入 更新 已删除 使用 MERGE 操作完成所有操作时。 这个简单的实用程序是为了...
COUNT :对一组内发生的事情进行累积计数 ------------------------------------------------------------------------------------------------- RANK :根据ORDER BY子句中表达式的值,从查询返回的每一行,计算...
按照id分组并计数,某个id号那一组的数量超过1条则认为重复。 如何查询重复的数据 select 字段1,字段2,count(*) from 表名 group by 字段1,字段2 having count(*) > 1 PS:将上面的>号改为=号就可以查询出没有...
oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 第一章 Oracle入门 一、 数据库概述 数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,它产生于距今五十年前。简单来说是本身可视...
Oracle中查询某个表的总字段数,要用SQL语句,或者在PL/SQL里面 代码如下:select count(column_name) from user_tab_columns where table_name=’T_B_AUDITOR’能够查出来指定的那张表的字段数。下面是通过大致查看...
8.2.2 计数函数-COUNT() 8.2.3 最大/最小值函数-MAX()/MIN() 8.2.4 均值函数-AVG() 8.2.5 聚合分析的重值处理 8.2.6 聚合函数的组合使用 8.3 组合查询 8.3.1 GROUP BY子句创建分组 8.3.2 ...
8.2.2 计数函数—count() 140 8.2.3 最大/最小值函数—max()/min() 143 8.2.4 均值函数—avg() 145 8.2.5 聚合分析的重值处理 147 8.2.6 聚合函数的组合使用 148 8.3 组合查询 148 8.3.1 group by子句创建分组...
1.count属性计数 ,可以得到集合的元素数量 2.delete方法 3.exists 判断这个元素是否存在,exists(x) 4.extend方法 不带参数加一个元素 extend(x)加x个元素 extend(x,y) 5.first属性,返回第一个元素...
如果指定列名,则DISTINCT只能用于COUNT(列名),DISTINCT不能用于COUNT(*)。 如:Select Distinct name From s_dept; Select Distinct dept_id,title From s_emp; 文本处理: TRIM()/LTRIM()/RTIRM():去空格。...
echo count($a); // 打印出3,因为该是数组有3个元素 // 用一个语句定义一个数组并赋值 $myphonebook = array ( "sbabu" => "5348", "keith" => "4829", "carole" => "4533" ); // 噢,忘了教长吧,让我们添加一个...
-- 首先,以超级管理员的身份登录oracle sqlplus sys/bjsxt as sysdba --然后,解除对scott用户的锁 alter user scott account unlock; --那么这个用户名就能使用了。 --(默认全局数据库名orcl) 1、...
mssql 2000 Access DB2 oracle 【mysql安装】 1、官方下载mysql win32 msi 2、点击安装 3、配置 4、查看是否安装成功 通过cmd 输入netstat -a搜索3306端口是否处于listening状态 【mysql服务的启动与停止】 1...
函数 AVG (平均) COUNT (计数) MAX (最大值) MIN (最小值) SUM (总合) SELECT "函数名"("栏位名") FROM "表格名" (10) COUNT .................................... .............. ..................................
set @strSQL = 'select count(*) as Total from [' + @tblName + '] where 1=1 安定 '+ @strWhere 2、收缩数据库 --重建索引 DBCC REINDEX DBCC INDEXDEFRAG --收缩数据和日志 DBCC SHRINKDB DBCC SHRINKFILE 3、...
set @strSQL = 'select count(*) as Total from [' + @tblName + '] where 1=1 安定 '+ @strWhere 2、收缩数据库 --重建索引 DBCC REINDEX DBCC INDEXDEFRAG --收缩数据和日志 DBCC SHRINKDB DBCC SHRINKFILE 3、...
set @strSQL = 'select count(*) as Total from [' + @tblName + '] where 1=1 安定 '+ @strWhere 2、收缩数据库 --重建索引 DBCC REINDEX DBCC INDEXDEFRAG --收缩数据和日志 DBCC SHRINKDB DBCC SHRINKFILE 3、...
实例143 使用线程池优化多线程编程 186 实例144 Object类中线程相关的方法 187 实例145 哲学家就餐问题 189 实例146 使用信号量实现线程同步 190 实例147 使用原子变量实现线程同步 191 实例148 使用事件分配线程...