2015年5月20日19:14:43 - 排序

1. 查看排序区内存的大小以及设置

实际排序所用到的内存、磁盘的统计信息:

pga_aggregate_target:此参数用来指定所有session总计可以使用最大PGA内存 olap:50% oltp:20%

sqlSQL> show parameter pga_aggre

NAME TYPE VALUE

------------------------------------ ---------------------- ------------------------------

pga_aggregate_target big integer 0

SQL> show parameter workarea_size_policy

workarea_size_policy:此参数用于开关PGA内存自动管理功能 auto:自动分配sort_area_size 属于workarea 如果需要经常排序就需要把这个值设置大点

sqlSQL> show parameter workarea_size_policy

NAME TYPE VALUE

------------------------------------ ---------------------- ------------------------------

workarea_size_policy string AUTO

select name, value from v$sysstat where name like ‘sort%’; select * from v$pgastat;

sqlSQL> select name , value from v$sysstat where name like 'sort%';

NAME VALUE

-------------------------------------------------------------------------------------------------------------------------------- ----------

sorts (memory) 4283

sorts (disk) 0

sorts (rows) 40823

2. 比较以下操作

select * from customers;

sqlSQL> set autotrace traceonly

SQL> select * from customers;

已选择55500行。

已用时间: 00: 00: 01.93

执行计划

----------------------------------------------------------

Plan hash value: 2008213504

-------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

-------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 55500 | 9810K| 406 (1)| 00:00:05 |

| 1 | TABLE ACCESS FULL| CUSTOMERS | 55500 | 9810K| 406 (1)| 00:00:05 |

-------------------------------------------------------------------------------

统计信息

----------------------------------------------------------

1 recursive calls

0 db block gets

5057 consistent gets

1455 physical reads

0 redo size

10855625 bytes sent via SQL*Net to client

41109 bytes received via SQL*Net from client

3701 SQL*Net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

55500 rows processed

select * from customers order by cust_last_name;

sqlSQL> select * from customers order by cust_last_name;

已选择55500行。

已用时间: 00: 00: 01.93

执行计划

----------------------------------------------------------

Plan hash value: 2792773903

----------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |

----------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 55500 | 9810K| | 2612 (1)| 00:00:32 |

| 1 | SORT ORDER BY | | 55500 | 9810K| 12M| 2612 (1)| 00:00:32 |

| 2 | TABLE ACCESS FULL| CUSTOMERS | 55500 | 9810K| | 406 (1)| 00:00:05 |

----------------------------------------------------------------------------------------

统计信息

----------------------------------------------------------

1 recursive calls

0 db block gets

1459 consistent gets

1454 physical reads

0 redo size

6278979 bytes sent via SQL*Net to client

41109 bytes received via SQL*Net from client

3701 SQL*Net roundtrips to/from client

1 sorts (memory)

0 sorts (disk)

55500 rows processed

可以看到使用order by用到了额外的12M内存

3. 在cust_last_name创建b*索引

没建索引:

sqlexplain plan for select cust_last_name from customers order by cust_last_name;

sqlSQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT

------------------------------------------------------------------------------------------------------------------

Plan hash value: 2792773903

----------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |

----------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 55500 | 433K| | 610 (1)| 00:00:08 |

| 1 | SORT ORDER BY | | 55500 | 433K| 880K| 610 (1)| 00:00:08 |

| 2 | TABLE ACCESS FULL| CUSTOMERS | 55500 | 433K| | 405 (1)| 00:00:05 |

----------------------------------------------------------------------------------------

建立索引:

sqlcreate index lastname_idx on customers(cust_last_name);

sqlexplain plan for select /*+ index(c lastname_idx) */ cust_last_name from customers order by cust_last_name;

执行计划:

sqlSQL> explain plan for select /*+ index(c lastname_idx) */ cust_last_name from customers order by cust_last_name;

已解释。

已用时间: 00: 00: 00.00

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT

------------------------------------------------------------------------------------------------------------------

Plan hash value: 3470560620

---------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

---------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 55500 | 433K| 143 (1)| 00:00:02 |

| 1 | INDEX FULL SCAN | LASTNAME_IDX | 55500 | 433K| 143 (1)| 00:00:02 |

---------------------------------------------------------------------------------

可以发现在一列建立索引后,对该列进行排序操作不需要再执行排序操作,

他会根据索引来进行查询(索引中本来就已经排好序)

结论

建立索引可以节省排序操作的时间。

4. 查询前十条记录

通常我们都会:

sqlselect cust_last_name from customers where rownum<=20 order by 1;

sqlSQL> select cust_last_name from customers where rownum<=20 order by 1;

CUST_LAST_NAME

--------------------------------------------------------------------------------

Everett

Everett

Everett

Everett

Everett

Everett

Everett

Everett

Everett

Ruddy

Ruddy

CUST_LAST_NAME

--------------------------------------------------------------------------------

Ruddy

Ruddy

Ruddy

Ruddy

Ruddy

Ruddy

Ruddy

Ruddy

Ruddy

已选择20行。

这样是错误的,因为在oracle中where永远都是先执行的也就先取20条再排序。

正确的做法是使用子查询:

sqlselect cust_last_name from (select * from customers order by cust_last_name) where rownum<10;

sqlSQL>select cust_last_name from (select * from customers order by cust_last_name) where rownum<10;

CUST_LAST_NAME

--------------------------------------------------------------------------------

Aaron

Aaron

Aaron

Aaron

Aaron

Aaron

Aaron

Aaron

Aaron

Aaron

Aaron

CUST_LAST_NAME

--------------------------------------------------------------------------------

Aaron

Aaron

Aaron

Aaron

Aaron

Aaron

Aaron

Aaron

Aaron

已选择20行。

没建索引:

sqlPLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------------------------------

Plan hash value: 1285511559

---------------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |

---------------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 9 | 198 | | 2612 (1)| 00:00:32 |

|* 1 | COUNT STOPKEY | | | | | | |

| 2 | VIEW | | 55500 | 1192K| | 2612 (1)| 00:00:32 |

|* 3 | SORT ORDER BY STOPKEY| | 55500 | 9810K| 12M| 2612 (1)| 00:00:32 |

| 4 | TABLE ACCESS FULL | CUSTOMERS | 55500 | 9810K| | 406 (1)| 00:00:05 |

---------------------------------------------------------------------------------------------

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

1 - filter(ROWNUM<10)

3 - filter(ROWNUM<10)

已选择17行。

建立索引后:

sqlPLAN_TABLE_OUTPUT

----------------------------------------------------------------------------------------------------

Plan hash value: 3026242074

----------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

----------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 9 | 198 | 4 (0)| 00:00:01 |

|* 1 | COUNT STOPKEY | | | | | |

| 2 | VIEW | | 9 | 198 | 4 (0)| 00:00:01 |

| 3 | INDEX FULL SCAN| LASTNAME_IDX | 9 | | 2 (0)| 00:00:01 |

----------------------------------------------------------------------------------

PLAN_TABLE_OUTPUT

----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

1 - filter(ROWNUM<10)

已选择15行。

建立索引后,子查询效率明显提高

同时select cust_last_name from customers where rownum<=10 order by cust_last_name;和上面的结果已经大不相同。

sqlSQL> select cust_last_name from customers where rownum<=10 order by cust_last_name;

CUST_LAST_NAME

--------------------------------------------------------------------------------

Aaron

Aaron

Aaron

Aaron

Aaron

Aaron

Aaron

Aaron

Aaron

Aaron

已选择10行。

执行计划:

sqlSQL> explain plan for

2 select cust_last_name from customers where rownum<=10 order by cust_last_name;

已解释。

已用时间: 00: 00: 00.00

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT

---------------------------------------------------------------------------------------------

Plan hash value: 2820001957

---------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

---------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 10 | 80 | 2 (0)| 00:00:01 |

|* 1 | COUNT STOPKEY | | | | | |

| 2 | INDEX FULL SCAN| LASTNAME_IDX | 55500 | 433K| 2 (0)| 00:00:01 |

---------------------------------------------------------------------------------

Predicate Information (identified by operation id):

PLAN_TABLE_OUTPUT

---------------------------------------------------------------------------------------------

---------------------------------------------------

1 - filter(ROWNUM<=10)

已选择14行。

竟然不是刚刚那样乱的。

结论

建立索引能够对提高子查询的性能,并且查询前十条记录不再需要使用子查询, 因为建立好索引后已经是排好序的,只要根据索引从表中拿出前十条记录即可。

5. 分组与索引

首先先建立一个表

sqlSQL> create table s as select * from sales;

表已创建。

s表与sales表的数据完全是一致的但s表没有sales表上的索引。

然后我们看一下执行计划:

sqlSQL> explain plan for

2 select cust_id,avg(amount_sold) from s group by cust_id;

已解释。

已用时间: 00: 00: 00.23

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT

------------------------------------------------------------------------------------

Plan hash value: 1912481676

---------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

---------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 785K| 19M| 1271 (4)| 00:00:16 |

| 1 | HASH GROUP BY | | 785K| 19M| 1271 (4)| 00:00:16 |

| 2 | TABLE ACCESS FULL| S | 785K| 19M| 1236 (1)| 00:00:15 |

---------------------------------------------------------------------------

Note

PLAN_TABLE_OUTPUT

------------------------------------------------------------------------------------

-----

- dynamic sampling used for this statement (level=2)

已选择13行。

我们再看一下sales表(即建立了索引的表):

sqlSQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------------

Plan hash value: 2820001957

---------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

---------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 10 | 80 | 2 (0)| 00:00:01 |

|* 1 | COUNT STOPKEY | | | | | |

| 2 | INDEX FULL SCAN| LASTNAME_IDX | 55500 | 433K| 2 (0)| 00:00:01 |

---------------------------------------------------------------------------------

Predicate Information (identified by operation id):

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------------

---------------------------------------------------

1 - filter(ROWNUM<=10)

已选择14行。

结论

group by的一列上建立索引group by 性能更佳。

下面是关于order by 升序降序的执行计划可以看出建立索引升降序对排序不会影响性能

升序:

sqlSQL> select cust_last_name from customers where rownum <= 10 order by cust_last_name;

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------------

Plan hash value: 2820001957

---------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

---------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 10 | 80 | 2 (0)| 00:00:01 |

|* 1 | COUNT STOPKEY | | | | | |

| 2 | INDEX FULL SCAN| LASTNAME_IDX | 55500 | 433K| 2 (0)| 00:00:01 |

---------------------------------------------------------------------------------

Predicate Information (identified by operation id):

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------------

---------------------------------------------------

1 - filter(ROWNUM<=10)

已选择14行。

降序:

sqlSQL> select cust_last_name from customers where rownum <= 10 order by cust_last_name;

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------------------------

Plan hash value: 1596600344

--------------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

--------------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 9 | 72 | 2 (0)| 00:00:01 |

|* 1 | COUNT STOPKEY | | | | | |

| 2 | INDEX FULL SCAN DESCENDING| LASTNAME_IDX | 55500 | 433K| 2 (0)| 00:00:01 |

--------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------------------------

---------------------------------------------------

1 - filter(ROWNUM<10)

已选择14行。

oracle 排序太慢,Oracle 排序优化相关推荐

  1. oracle空格太多,Oracle Sql字符串多余空格处理方法初记

    (一)问题提出: 不知道大家有没有遇到过这样的情况,同样的sql在pl/sql下面执行正常,但是拷贝到表字段中,点击提交的时候老是会报ORA-01480: STR 绑定值的结尾 Null错误,如图: ...

  2. oracle+sql+按中文拼音排序,Oracle 中文字段进行排序的sql语句

    Oracle 中文字段进行排序的sql语句 1)按笔画排序 select * from Table order by nlssort(columnName,'NLS_SORT=SCHINESE_STR ...

  3. oracle排序特别慢,Oracle 排序是件很有意思的事

    以下的文章主要是对Oracle排序中的几种常用排序的介绍,你会发现Oracle 排序是一件很有意思的事,以下就是文章的具体内容的描述,以下是文章的具体介绍,望你浏览完以下的内容会有所收获. 按拼音排序 ...

  4. 数据库中自定义排序规则,Mysql中自定义字段排序规则,Oracle中自定义字段排序规则,decode函数的用法,field函数的用法

    数据库中自定义排序 场景:有一张banner表,表中有一个status字段,有0, 1, 2三个状态位,我想要 1,0,2的自定义排序(这里是重点),然后再进行之上对sequence字段进行二次排序( ...

  5. oracle菜鸟学习之 分析函数-排序

    oracle菜鸟学习之 分析函数-排序 排序函数 1.row_number:返回连续的排序,无论值是否相等 2.rank:具有相等值得行排序相同,序数值随后跳跃 3.dense_rank:具有相等值得 ...

  6. Oracle数据库之过滤和排序

    oracle安装参照: Oracle数据库之安装教程 Oracle数据库总结: Oracle数据库之基本查询 Oracle数据库之单行函数 Oracle数据库之多行函数 Oracle数据库之多表查询 ...

  7. MySQL 如何实现 Oracle 的 row_number() over() 分组排序功能

    文章目录 Oracle 的分组排序 MySQL 的分组排序 分析需求 创建模拟数据 SQL 实现 结果演示 Oracle 的分组排序 Oracle 的分组排序函数的语法格式如下: ROW_NUMBER ...

  8. oracle生成顺序编号,Oracle排序以及序号的输出 | 学步园

    在一般Select语句中我们通过Order by ...Asc/Desc来进行排序.但是这种排序方式在输出时,不包含排序后的序号信息. 现在介绍一下Oracle中可以用于排序输出的方法. 1. RAN ...

  9. oracle和mysql查询条件排序_Oracle数据库中ORDERBY排序和查询按IN条件的顺序输出

    ORDER BY非稳定的排序提一个问题: oracle在order by 排序时,是稳定排序算法吗? 发现用一个type进行排序后,做分页查询,第一页的数据和第二页的数据有重复 怀疑是order by ...

最新文章

  1. CMOS及CCD感光sensor的主要技术参数解析
  2. 今天浅谈功能测试基础
  3. Android学习笔记13-Acitivty与Fragment通信
  4. 后端传给前端 无限极分类_学徒|记者亲身体验垃圾分拣,臭到崩溃!我们还有什么理由不做垃圾分类?...
  5. VTK:图表之ColorEdges
  6. k8s的list-watch机制和 pod调度约束
  7. Angular本地数据存储LocalStorage
  8. python try 异常处理 史上最全
  9. 离线登陆_iphone手机,苹果手机如何登陆网易163邮箱
  10. linux 查看cuda版本_Ubuntu18.04+Tensorflow GPU版本环境搭建
  11. 在leangoo里怎么添加泳道?
  12. OCJP考试习题(1z0-808)(一)
  13. EPLAN电气设计入门学习笔记
  14. wordpress设置首页为特定页
  15. git 设置代理的方法
  16. 软件工程小组需求分析--快递代领
  17. torch.bmm() 与 torch.matmul()
  18. Trying to start MapKit location updates without prompting for location authorization. Must call -[CL
  19. JavaScript刮奖效果(jquery图片刮奖插件)
  20. application.yaml配置详解

热门文章

  1. 如何确定哪个Nintendo Switch适合您
  2. (转)GPU图形绘制管线
  3. 返程高峰期,这些防御姿势必不可少,请大家细读,谢谢:吐血整理!返程复工保命指南
  4. USB 4种充电类型
  5. 现阶段数字版权主要技术
  6. 剑指奥迪Q7 凯迪拉克XT6突围“二线豪华”将于7月份上市 | 2019上海车展
  7. 3D位置语音,引领吃鸡游戏体验升级
  8. iPhone短信删除了怎么恢复
  9. React的setTimeout定时任务,和setTimeout的定时无效
  10. 骨传导耳机通话质量怎么样、通话品质好的耳机排名