`
hypgr
  • 浏览: 276938 次
社区版块
存档分类
最新评论

oracle count计数的优化

阅读更多

在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数据库性能优化宝典

    13. **计算记录条数**:通过COUNT(*)等统计操作获取记录数,优化计数方法可以减少全表扫描,尤其是对于大表。 14. **用WHERE子句替换HAVING子句**:在能的情况下,将过滤条件移到WHERE子句中,以避免在GROUP BY后的...

    oracle优化篇及常用函数

    5. **聚合函数**:如`COUNT()`计数,`SUM()`求和,`AVG()`求平均值,`MAX()`和`MIN()`找出最大值和最小值。 6. **分组和窗口函数**:如`GROUP BY`用于分组,`HAVING`过滤分组后的结果,`OVER()`配合窗口函数如`RANK...

    oracle sqL 性能优化1

    ### Oracle SQL性能优化详解 #### 一、Oracle优化器模式选择与成本计算 在Oracle数据库中,优化器(Optimizer)负责选择执行计划的最佳路径。Oracle提供了三种不同的优化器模式:`RULE`、`COST` 和 `CHOOSE`。这些...

    ORACLE9i_优化设计与系统调整

    第一部分 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...

    Oracle SQL性能优化最佳实践.docx

    12. **计算记录条数**:COUNT(*)操作可能导致全表扫描,如果仅需计数非NULL列,使用COUNT(列名)更高效。 13. **用Where子句替换Having子句**:在能将过滤条件移到WHERE子句时,避免在HAVING子句中使用,因为HAVING...

    oracle SQL优化实例

    ### Oracle SQL优化实例详解 #### 一、减少I/O操作 在Oracle数据库中,I/O操作通常是查询执行过程中最耗时的部分之一。因此,减少I/O操作可以显著提高查询性能。 **示例代码:** ```sql SELECT COUNT(CASE WHEN ...

    Oracle-SQL优化(内部资料).docx

    ### Oracle SQL性能优化关键知识点 #### 一、选择正确的基础表 在进行多表连接查询时,选择正确的基础表对于提高查询效率至关重要。基础表的选择原则通常基于表的数据量大小和连接方式。文档中提到了两种不同的连接...

    oracle sql 优化

    ### Oracle SQL 优化知识点 #### 一、Oracle SQL 基础理解与重要性 在数据库管理系统中,Oracle SQL 是一种强大的工具,用于查询、管理、优化数据存储和检索过程。Oracle SQL 的优化对于提高查询性能、降低系统...

    linux下oracle创建实例总结

    - `db_file_multiblock_read_count`:设置多数据块读取计数。 - `dispatchers`:设置调度程序。 - `job_queue_processes`:设置作业队列进程数。 完成以上步骤后,即可成功创建一个新的 Oracle 数据库实例。这涉及...

    oracle数据库执行计划

    Oracle提供了多种优化器模式,主要包括基于规则的优化器(Rule-Based Optimizer, RBO)和基于成本的优化器(Cost-Based Optimizer, CBO)。 - **RBO**:基于表和索引的定义信息来确定执行计划。它遵循一组预定义的规则...

    Oracle 常用SQL技巧经典收藏

    5. **计数技巧**:在计算记录数时,一般认为COUNT(*)比COUNT(1)稍快,因为COUNT(*)包括NULL值,而COUNT(1)会忽略它们。如果有索引可用,直接对索引列进行计数通常是最快的。 6. **使用WHERE子句替换HAVING子句**:...

    Oracle数据访问 获取记录总数

    此外,OO4O库提供了更高级的自动化接口,可以直接通过Oracle OLE DB Provider进行操作,但对于简单的记录计数任务,MFC扩展库已经足够高效。 通过以上步骤,我们就可以在VC6环境下使用MFC和OO4O库来访问Oracle...

    手动创建oracle实例

    - **db_file_multiblock_read_count**: 多块读取计数,用于优化大块连续读取的效率。 - **open_cursors**: 打开游标的最大数量,影响并发查询的性能。 - **db_domain** 和 **db_name**: 定义数据库的名称和域名,...

    SQL(oracle)教程(PPT版)

    5. **聚合函数**:SUM、AVG、MAX、MIN和COUNT等用于对一组值进行计算,如求和、平均值、最大值、最小值和计数。 6. **子查询**:嵌套在其他查询中的查询称为子查询,可以用于比较、过滤或获取满足特定条件的数据。 ...

    oracle 函数大全 参考函数 手册 速查 chm格式

    6. 聚合函数:如COUNT(计数)、SUM(求和)、AVG(平均值)、MAX/MIN(最大值/最小值)等,用于汇总数据。 7. 位操作函数:如BITAND(按位与)、BITOR(按位或)、BITNOT(按位非)等,处理二进制数据。 8. 非...

    oracle学习日志总结

    `COUNT(1)`通常比`COUNT(*)`更快,因为计算单个列的计数比计算所有列更有效。 7. **数据类型匹配**:确保在表连接时使用相同的数据类型,以避免隐式类型转换导致的性能损失。在存储过程中,也要注意参数和数据类型...

    oracle_11gR27

    Oracle 11g R2是Oracle数据库的一个重要版本,提供了许多增强的功能和性能优化,尤其在数据管理和操作方面。在这个版本中,对于SQL操作(包括SELECT、INSERT、UPDATE和DELETE)以及常用函数的理解和应用是数据库管理...

    oracle中文电子书

    5. **聚合函数**:如COUNT(计数)、SUM(求和)、AVG(平均值)、MAX/MIN(最大/最小值),这些函数在数据分析和报表生成中不可或缺。 6. **逻辑函数**:如IFNULL或NVL(处理空值),以及AND/OR/NOT(逻辑运算),...

Global site tag (gtag.js) - Google Analytics