在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 |
分享到:
相关推荐
13. **计算记录条数**:通过COUNT(*)等统计操作获取记录数,优化计数方法可以减少全表扫描,尤其是对于大表。 14. **用WHERE子句替换HAVING子句**:在能的情况下,将过滤条件移到WHERE子句中,以避免在GROUP BY后的...
5. **聚合函数**:如`COUNT()`计数,`SUM()`求和,`AVG()`求平均值,`MAX()`和`MIN()`找出最大值和最小值。 6. **分组和窗口函数**:如`GROUP BY`用于分组,`HAVING`过滤分组后的结果,`OVER()`配合窗口函数如`RANK...
### Oracle SQL性能优化详解 #### 一、Oracle优化器模式选择与成本计算 在Oracle数据库中,优化器(Optimizer)负责选择执行计划的最佳路径。Oracle提供了三种不同的优化器模式:`RULE`、`COST` 和 `CHOOSE`。这些...
第一部分 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...
12. **计算记录条数**:COUNT(*)操作可能导致全表扫描,如果仅需计数非NULL列,使用COUNT(列名)更高效。 13. **用Where子句替换Having子句**:在能将过滤条件移到WHERE子句时,避免在HAVING子句中使用,因为HAVING...
### Oracle SQL优化实例详解 #### 一、减少I/O操作 在Oracle数据库中,I/O操作通常是查询执行过程中最耗时的部分之一。因此,减少I/O操作可以显著提高查询性能。 **示例代码:** ```sql SELECT COUNT(CASE WHEN ...
### Oracle SQL性能优化关键知识点 #### 一、选择正确的基础表 在进行多表连接查询时,选择正确的基础表对于提高查询效率至关重要。基础表的选择原则通常基于表的数据量大小和连接方式。文档中提到了两种不同的连接...
### Oracle SQL 优化知识点 #### 一、Oracle SQL 基础理解与重要性 在数据库管理系统中,Oracle SQL 是一种强大的工具,用于查询、管理、优化数据存储和检索过程。Oracle SQL 的优化对于提高查询性能、降低系统...
- `db_file_multiblock_read_count`:设置多数据块读取计数。 - `dispatchers`:设置调度程序。 - `job_queue_processes`:设置作业队列进程数。 完成以上步骤后,即可成功创建一个新的 Oracle 数据库实例。这涉及...
Oracle提供了多种优化器模式,主要包括基于规则的优化器(Rule-Based Optimizer, RBO)和基于成本的优化器(Cost-Based Optimizer, CBO)。 - **RBO**:基于表和索引的定义信息来确定执行计划。它遵循一组预定义的规则...
5. **计数技巧**:在计算记录数时,一般认为COUNT(*)比COUNT(1)稍快,因为COUNT(*)包括NULL值,而COUNT(1)会忽略它们。如果有索引可用,直接对索引列进行计数通常是最快的。 6. **使用WHERE子句替换HAVING子句**:...
此外,OO4O库提供了更高级的自动化接口,可以直接通过Oracle OLE DB Provider进行操作,但对于简单的记录计数任务,MFC扩展库已经足够高效。 通过以上步骤,我们就可以在VC6环境下使用MFC和OO4O库来访问Oracle...
- **db_file_multiblock_read_count**: 多块读取计数,用于优化大块连续读取的效率。 - **open_cursors**: 打开游标的最大数量,影响并发查询的性能。 - **db_domain** 和 **db_name**: 定义数据库的名称和域名,...
5. **聚合函数**:SUM、AVG、MAX、MIN和COUNT等用于对一组值进行计算,如求和、平均值、最大值、最小值和计数。 6. **子查询**:嵌套在其他查询中的查询称为子查询,可以用于比较、过滤或获取满足特定条件的数据。 ...
6. 聚合函数:如COUNT(计数)、SUM(求和)、AVG(平均值)、MAX/MIN(最大值/最小值)等,用于汇总数据。 7. 位操作函数:如BITAND(按位与)、BITOR(按位或)、BITNOT(按位非)等,处理二进制数据。 8. 非...
`COUNT(1)`通常比`COUNT(*)`更快,因为计算单个列的计数比计算所有列更有效。 7. **数据类型匹配**:确保在表连接时使用相同的数据类型,以避免隐式类型转换导致的性能损失。在存储过程中,也要注意参数和数据类型...
Oracle 11g R2是Oracle数据库的一个重要版本,提供了许多增强的功能和性能优化,尤其在数据管理和操作方面。在这个版本中,对于SQL操作(包括SELECT、INSERT、UPDATE和DELETE)以及常用函数的理解和应用是数据库管理...
5. **聚合函数**:如COUNT(计数)、SUM(求和)、AVG(平均值)、MAX/MIN(最大/最小值),这些函数在数据分析和报表生成中不可或缺。 6. **逻辑函数**:如IFNULL或NVL(处理空值),以及AND/OR/NOT(逻辑运算),...