`
Ordier
  • 浏览: 61548 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

sql语句 select count(*) from emp; 不使用索引问题

阅读更多
     自己在学习oracle优化课程的时候,想当然的以为count(*) 操作肯定是会走索引的。可是那天碰巧试试发现居然是全表扫描。
      这里把关于这个问题的解决的过程记录下来,以便以后查阅,也希望能给同时遇见这个问题的朋友一点帮助。

--打开执行计划
SQL> set autotrace traceonly
--刚开使的查询计划
SQL> select count(*) from emp;

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   SORT (AGGREGATE)
   2    1     TABLE ACCESS (FULL) OF 'EMP'




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


-- 使用 hints 仍然是全表扫描

SQL> select /*+ index(PK_EMP) */ count(*) from emp;


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1)
   1    0   SORT (AGGREGATE)
   2    1     TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=82)




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

--分析表
SQL> analyze table emp compute statistics;

表已分析。

-- 再次执行 则开始走索引
SQL> select count(*) from emp;


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1)
   1    0   SORT (AGGREGATE)
   2    1     INDEX (FULL SCAN) OF 'PK_EMP' (UNIQUE) (Cost=1 Card=14)




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

问题解决,但仍有许多需要解释一下的地方。

1. rbo与cbo
   rbo是基于规则的,在rbo下需要程序员自己分析然后指定应该使用那一个索引效率更高,也就是要使用hints。 而在cbo是基于cost的,这样sql引擎会自己计算用那个索引的cost最小,然后选择该索引执行sql语句。但是cbo需要有表的统计信息。
    rbo是oracle早期版本7i的特性,8i,9i是即支持rbo也支持cbo的 但oracle 10g就只有cbo了,所以在10g中oracle会自己对表进行分析,并保存表的统计信息。
    所以在没有对表进行分析的时候 走 rbo, 分析过的表走 cbo


2. 索引中不能含有null值,如果建索引的列不是 not null的,那么索引将不被使用。

其它索引不被使用的情况:
   1)当对同一个表的两个列(其中一个列为主键,一个列为索引) 进行比较时,索引有时不会被使用
   2)在where中出现 is null或者is not null时 索引不能被使用
   3)在where语句中存在有not function时 例:not in,not exist,<>,>,<等情形下索引不能被使用
   4)当使用了single-row function时 例nvl,to_char,lower等索引不能被使用
   5)当使用通配符号%或者_作为查询字符串的第一个字符时索引不会被使用

分享到:
评论

相关推荐

    SQL 语句 大全 帮助

    - **示例**: `PREPARE EmpSelect FROM 'SELECT * FROM Employees WHERE ID = ?';` #### 执行语句 (EXECUTE) - **语法**: `EXECUTE statement_name USING variable_list;` - **功能**: 用于执行准备好的动态SQL语句...

    SQL语句select用法详解

    ### SQL语句SELECT用法详解 #### 一、概述 SQL(Structured Query Language)是一种用于管理关系数据库的标准语言。在SQL中,`SELECT`语句是最常用的操作之一,主要用于从数据库表中检索数据。通过使用不同的子句...

    PLSQL 语句优化

    - **示例**:将 `SELECT * FROM EMP WHERE EMPNO IN (SELECT DEPTNO FROM DEPT WHERE LOC = 'MELB')` 替换为 `SELECT * FROM EMP WHERE EXISTS (SELECT NULL FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND DEPT....

    自己收藏的经典SQL语句

    ### 自己收藏的经典SQL语句 #### 数据库操作 **1. 创建数据库** - **命令格式**: `CREATE DATABASE database-name;` - **说明**: 此命令用于创建一个新的数据库。 - **示例**: `CREATE DATABASE myDatabase;` ...

    数据库面试题索引sql优化

    SELECT COUNT(1) FROM EMP E2 WHERE E2.DEPTNO = E1.DEPTNO AND E2.ENAME != E1.ENAME AND E2.SAL &gt;= E1.SAL ) ; ``` **解析:** 这是一个较为复杂的查询,使用了子查询和比较条件来找出每个部门中除了自身之外...

    SQL 习惯性优化.doc

    - **示例**:`SELECT * FROM table WHERE (SELECT COUNT(*) FROM other_table WHERE other_table.id = table.id) &gt; 0;` #### 十七、用WHERE子句替换HAVING子句 - **优化建议**:尽可能在WHERE子句中过滤数据,以...

    SQL优化 SQL 优化

    SELECT...FROM EMPE WHERE SAL &gt; 50000 AND JOB = 'MANAGER' AND 25 (SELECT COUNT(*) FROM EMP WHERE MGR = E.EMPNO); ``` **高效版本**: ```sql SELECT...FROM EMPE WHERE 25 (SELECT COUNT(*) FROM EMP WHERE ...

    SQL培训课件

    - **大小写不敏感**: SQL语句在大多数数据库系统中对大小写不敏感,但为了提高代码的可读性和一致性,建议统一使用大写或小写字母来书写SQL关键字。 - **多行书写**: SQL语句可以跨多行书写,以增强可读性。 - **...

    oracle考试题目.docx

    - SQL语句示例:`SELECT deptno, COUNT(*) AS emp_count FROM emp GROUP BY deptno HAVING COUNT(*) &gt;= 1;` - **列出各个部门的MANAGER(经理)的最低薪金。** - 首先需要确定经理的职位,假设为“MANAGER”。 -...

    mysql基本语法,增删改查大全总结,以及常用的sql语句总结

    SELECT * FROM emp WHERE idcard LIKE '%X'; -- 查询最后一位身份证号是X的员工 ``` - **聚合函数**: | 函数 | 功能 | | --- | --- | | COUNT | 统计数量 | | MAX | 最大值 | | MIN | 最小值 | | AVG | ...

    对于RULE优化器的一些SQL语句的优化的方法.txt

    ### 对于RULE优化器的一些SQL语句的优化方法 #### 一、理解RULE优化器及其在SQL查询中的作用 在数据库管理系统(DBMS)中,查询优化器是负责选择执行查询的最佳策略的关键组件之一。根据不同的优化算法,优化器...

    Oracle第一次考试

    Select count(*) from scott.emp; ``` - 查询每个部门的部门代码、薪水之和、平均薪水: ```sql Select empID, sum(laborage) as "薪水之和", avg(laborage) as "平均薪水" from emp group by empID; ``` 6. ...

    高效率常用的OracleSQL语句.txt

    WHERE E.ROWID = (SELECT MIN(X.ROWID) FROM EMP X WHERE X.EMP_NO = E.EMP_NO); ``` ### 4. TRUNCATE VS DELETE #### 知识点: - `TRUNCATE`操作会删除表中的所有数据,但不会记录任何日志信息,因此执行速度非常...

    sql语句优化

    - **使用 EXPLAIN 分析**:大多数数据库管理系统提供了`EXPLAIN`命令来查看SQL语句的执行计划,这对于理解查询是如何被执行的以及如何优化非常有帮助。 - **I/O 操作估计**:通过对执行计划中I/O操作的估计,可以...

    进入IT企业必会的Java笔试面试题卷一(含答案)

    9. **数据库分组查询**:在 SQL 中,使用 GROUP BY 语句进行分组查询时,任何在 SELECT 列表中非分组函数的列都必须出现在 GROUP BY 子句中。分组函数如 COUNT、SUM、AVG 等会忽略 NULL 值,并且只能出现在 SELECT ...

Global site tag (gtag.js) - Google Analytics