Nic*_*cko 0 sql oracle oracle11g
我试图更好地理解 Oracle SQL 在执行代码时如何确定不同值。我希望它一次只对一列起作用,然后将所有重复项放在一边,然后仅在这些行上比较下一列。这将通过验证下一列是否有任何重复项来继续,并且每次只有继续具有重复项的行才会进入下一步。这准确吗?此外,是否有一种方法可以用来确定从哪一列开始?有些列很可能有重复项,而其他列可能是不应包含任何重复项的键(假设联接或联合上没有发生重复)。
有两种基本方法:
散列往往更有效。
在以下情况下优先选择排序:
查询有一个order by- 数据无论如何都必须排序,所以没有必要进行散列和排序
不同表达式上有一个索引 - 数据库可以遍历索引来查找唯一值。如果它是唯一索引,则也可以跳过重复数据删除步骤,因为保证值是唯一的。
优化器也可能考虑其他因素(例如不同值的预期数量、空值数量、总数据集大小等)。优化器何时选择哈希排序的确切细节可能因版本而异。
这里有些例子:
-- distinct a non-indexed column => hash
select distinct salary from hr.employees;
select *
from table ( dbms_xplan.display_cursor ( format => 'BASIC' ) );
/*
----------------------------------------
| Id | Operation | Name |
----------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | HASH UNIQUE | |
| 2 | TABLE ACCESS FULL| EMPLOYEES |
----------------------------------------
*/
-- order by & distinct => sort
select distinct salary from hr.employees
order by salary;
select *
from table ( dbms_xplan.display_cursor ( format => 'BASIC' ) );
/*
----------------------------------------
| Id | Operation | Name |
----------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | SORT UNIQUE | |
| 2 | TABLE ACCESS FULL| EMPLOYEES |
----------------------------------------
*/
-- index on distinct column => sort
select distinct department_id from hr.employees;
select *
from table ( dbms_xplan.display_cursor ( format => 'BASIC' ) );
/*
------------------------------------------------
| Id | Operation | Name |
------------------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | SORT UNIQUE NOSORT| |
| 2 | INDEX FULL SCAN | EMP_DEPARTMENT_IX |
------------------------------------------------
*/
-- distinct of unique/primary index => no sort/hash needed! Just read the index
select distinct employee_id from hr.employees;
select *
from table ( dbms_xplan.display_cursor ( format => 'BASIC' ) );
/*
------------------------------------------
| Id | Operation | Name |
------------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | INDEX FULL SCAN | EMP_EMP_ID_PK |
------------------------------------------
*/
Run Code Online (Sandbox Code Playgroud)