查询排序最多的SQL语句:

WITH sql_workarea AS

(SELECT sql_id || '_' || child_number sql_id_child,

operation_type operation,

last_execution last_exec,

round(active_time / 1000000, 2) seconds,

optimal_executions || '/' || multipasses_executions olm,

'' || substr(sql_text, 1, 155) sql_text,

rank() over(ORDER BY active_time DESC) ranking

FROM v$sql_workarea

JOIN v$sql

USING (sql_id, child_number))

SELECT sql_id_child "SQL ID-CHILD",

seconds,

operation,

last_exec,

olm          "O/1/M",

sql_text

FROM sql_workarea

WHERE ranking <= 10

ORDER BY ranking;

10033跟踪排序:

alter session set tracefile_identifier=e10033;

alter session set events '10033 trace name context forever,level 1';

---- Sort Statistics ------------------------------

Initial runs                              14

Number of merges                          1

Input records                             55500

Output records                            55500

Disk blocks 1st pass                      1467

Total disk blocks used                    1451

Total number of comparisons performed     699074

Comparisons performed by in-memory sort 485849

Comparisons performed during merge      213212

Comparisons while searching for key in-memory 13

Number of seeks in final run              55500

Temp segments allocated                   1

Extents allocated                         12

Uses version 2 sort

Uses asynchronous IO

---- Run Directory Statistics ----

Run directory block reads (buffer cache)  15

Block pins (for run directory)            1

Block repins (for run directory)          14

Maximum input run size (in blocks)        109

Minimum input run size (in blocks)        32

Average input run size (in blocks)        104

---- Direct Write Statistics -----

Write slot size                           49152

Write slots used during in-memory sort    2

Number of direct writes                   247

Num blocks written (with direct write)    1449

Block pins (for sort records)             1449

Waits for async writes                    199

---- Direct Read Statistics ------

Size of read slots for output             32768

Number of read slots for output           32

Number of direct sync reads               30

Number of blocks read synchronously       95

Number of direct async reads              343

Number of blocks read asynchronously      1354

使用索引来规避排序

如果在order by字句中的部分或者全部列上存在索引,oracle有可能使用索引来按照要求的顺序获取记录,因此也避免了排序操作。

假如索引是出现在与orde by字句里的列相同的列上,oracle可以直接从索引中按照索引排序的顺序读取记录,然而,按键的顺序读取记录需要一块接一块地全扫描索引叶子块。虽然快速全扫描比全索引扫描高校得多,但是快速全扫描无法按索引顺序返回记录,因此也不能用来避免排序操作。

SQL> select * from customers order by cust_last_name,cust_first_name,cust_year_of_birth;

55500 rows selected.

Execution Plan

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

Plan hash value: 2792773903

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

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

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

|   0 | SELECT STATEMENT   |        | 55500 |  9810K|       |  2609  (1)| 00:00:02 |

|   1 |  SORT ORDER BY    |        | 55500 |  9810K|    12M|  2609  (1)| 00:00:02 |

|   2 |   TABLE ACCESS FULL| CUSTOMERS | 55500 |  9810K|       |   405  (1)| 00:00:01 |

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

Statistics

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

12  recursive calls

15  db block gets

1456  consistent gets

2903  physical reads

0  redo size

6366362  bytes sent via SQL*Net to client

41213  bytes received via SQL*Net from client

3701  SQL*Net roundtrips to/from client

0  sorts (memory)

1  sorts (disk)

55500  rows processed

建索引后:

SQL> create index cust_namedob_i on customers(cust_last_name,cust_first_name,cust_year_of_birth);

Index created.

SQL> select /*+ index(customers,cust_namedob_i) */ * from customers order by cust_last_name,cust_first_name,cust_year_of_birth;

55500 rows selected.

Execution Plan

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

Plan hash value: 1819843466

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

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

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

|   0 | SELECT STATEMENT     |       | 55500 | 9810K| 20550   (1)| 00:00:15 |

|   1 |  TABLE ACCESS BY INDEX ROWID| CUSTOMERS      | 55500 | 9810K| 20550   (1)| 00:00:15 |

|   2 |   INDEX FULL SCAN     | CUST_NAMEDOB_I | 55500 |      |  225   (0)| 00:00:01 |

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

Statistics

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

1  recursive calls

0  db block gets

26557  consistent gets

1708  physical reads

0  redo size

6366312  bytes sent via SQL*Net to client

41213  bytes received via SQL*Net from client

3701  SQL*Net roundtrips to/from client

0  sorts (memory)

0  sorts (disk)

55500  rows processed

虽然使用索引可能就不再需要排序了,但是同时读取索引和表块,以及按块顺次读取这种并不高效的扫描方式所带来的开销,比使用全表扫描读取表块的方式要欠佳很多,通常,这意味为了避免排序而使用索引,实际上会导致更差的性能。然而使用索引在检索第一行记录时速度更快,因为一旦需要的记录被检索到,它会立即返回。相比之下排序的方法要求在任一记录返回之前,全部记录都必须被检索出来并完成排序。因此,在优化器目标为FIRST_ROWS_N时,优化器倾向于使用索引,而在目标是ALL_ROWS时,则会使用全表扫描。

另一个基于索引的获取比先扫描再获取要更优异的场景是当内存极其有限时。如果可用于排序的内存是受限的,读写临时段所需要IO将超过索引和和表扫描所包含的额外的IO开销。当然如果能够分配更多的内存,它的表现会好很多的,但是如果这是不可能的,你或许应该使用INDEX提示来避免排序。

聚合操作

聚合炒作(如SUM和AVG)必须处理输入的数据每一行记录,因此,它们通常和全表扫描联系在一起。

SQL> select sum(quantity_sold) from sales;

Execution Plan

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

Plan hash value: 3519235612

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

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

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

|   0 | SELECT STATEMENT     |      |    1 |    3 |  525   (2)| 00:00:01 |      |      |

|   1 |  SORT AGGREGATE      |      |    1 |    3 |    |      |      |      |

|   2 |   PARTITION RANGE ALL|      |  918K| 2691K|  525   (2)| 00:00:01 |    1 |   28 |

|   3 |    TABLE ACCESS FULL | SALES |  918K| 2691K|  525   (2)| 00:00:01 |    1 |   28 |

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

Statistics

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

2429  recursive calls

2  db block gets

5371  consistent gets

1714  physical reads

0  redo size

538  bytes sent via SQL*Net to client

524  bytes received via SQL*Net from client

2  SQL*Net roundtrips to/from client

183  sorts (memory)

0  sorts (disk)

1  rows processed

SQL> select /*+ index(sales,index_sl) */ sum(quantity_sold) from sales;

SUM(QUANTITY_SOLD)

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

918843

Execution Plan

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

Plan hash value: 3788238680

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

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

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

|   0 | SELECT STATEMENT |     |   1 |   3 |  2316   (1)| 00:00:02 |

|   1 |  SORT AGGREGATE  |     |   1 |   3 |   |     |

|   2 |   INDEX FULL SCAN| INDEX_SL | 918K|  2691K|  2316   (1)| 00:00:02 |

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

Statistics

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

1  recursive calls

0  db block gets

2311  consistent gets

2314  physical reads

0  redo size

538  bytes sent via SQL*Net to client

524  bytes received via SQL*Net from client

2  SQL*Net roundtrips to/from client

0  sorts (memory)

0  sorts (disk)

1  rows processed

最大值和最小值,

与大多数其他的聚合操作不同,如果在相关列存在索引,MAX和MIN操作并不需要读取每一行记录。如果存在B树索引,我们可以通过检查第一个或最后一个索引项来确定最大值或最小值,这仅需要3-5个逻辑读的开销:

SQL> select max(amount_sold) from sales;

MAX(AMOUNT_SOLD)

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

1782.72

Execution Plan

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

Plan hash value: 781264156

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

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

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

|   0 | SELECT STATEMENT    |       |    1 |    5 |    3   (0)| 00:00:01 |

|   1 |  SORT AGGREGATE     |       |    1 |    5 |    |      |

|   2 |   INDEX FULL SCAN (MIN/MAX)| AMOUNT_SOLD_IDX |    1 |    5 |    3   (0)| 00:00:01 |

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

Statistics

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

1  recursive calls

0  db block gets

3  consistent gets

8  physical reads

0  redo size

536  bytes sent via SQL*Net to client

524  bytes received via SQL*Net from client

2  SQL*Net roundtrips to/from client

0  sorts (memory)

0  sorts (disk)

1  rows processed

同时找出最大值和最小值,

SQL> select max(amount_sold),min(amount_sold) from sales;

MAX(AMOUNT_SOLD) MIN(AMOUNT_SOLD)

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

1782.72       6.4

Execution Plan

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

Plan hash value: 3519235612

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

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

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

|   0 | SELECT STATEMENT     |      |    1 |    5 |  525   (2)| 00:00:01 |      |      |

|   1 |  SORT AGGREGATE      |      |    1 |    5 |    |      |      |      |

|   2 |   PARTITION RANGE ALL|      |  918K| 4486K|  525   (2)| 00:00:01 |    1 |   28 |

|   3 |    TABLE ACCESS FULL | SALES |  918K| 4486K|  525   (2)| 00:00:01 |    1 |   28 |

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

Statistics

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

1  recursive calls

0  db block gets

1635  consistent gets

1619  physical reads

0  redo size

618  bytes sent via SQL*Net to client

524  bytes received via SQL*Net from client

2  SQL*Net roundtrips to/from client

0  sorts (memory)

0  sorts (disk)

1  rows processed

实际上分别提交MAX和MIN查询然后将结果合并到一起是一种更好的方法:

SELECT max_sold, min_sold

FROM (SELECT MAX(amount_sold) max_sold FROM sales) maxt,

2    3         (SELECT MIN(amount_sold) min_sold FROM sales) mint;

MAX_SOLD   MIN_SOLD

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

1782.72   6.4

Execution Plan

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

Plan hash value: 3650580342

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

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

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

|   0 | SELECT STATEMENT      |         |     1 |    26 |     6  (0)| 00:00:01 |

|   1 |  NESTED LOOPS       |         |     1 |    26 |     6  (0)| 00:00:01 |

|   2 |   VIEW        |         |     1 |    13 |     3  (0)| 00:00:01 |

|   3 |    SORT AGGREGATE      |         |     1 |     5 |     |        |

|   4 |     INDEX FULL SCAN (MIN/MAX)| AMOUNT_SOLD_IDX |     1 |     5 |     3  (0)| 00:00:01 |

|   5 |   VIEW        |         |     1 |    13 |     3  (0)| 00:00:01 |

|   6 |    SORT AGGREGATE      |         |     1 |     5 |     |        |

|   7 |     INDEX FULL SCAN (MIN/MAX)| AMOUNT_SOLD_IDX |     1 |     5 |     3  (0)| 00:00:01 |

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

Statistics

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

1  recursive calls

0  db block gets

6  consistent gets

5  physical reads

0  redo size

602  bytes sent via SQL*Net to client

524  bytes received via SQL*Net from client

2  SQL*Net roundtrips to/from client

0  sorts (memory)

0  sorts (disk)

1  rows processed

前N 查询

如何获取一个表的前10行记录,

错误写法:

SQL> SELECT * FROM sales WHERE rownum <= 10 ORDER BY amount_sold DESC;

PROD_ID    CUST_ID TIME_ID    CHANNEL_ID   PROMO_ID QUANTITY_SOLD AMOUNT_SOLD

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

13   987 1998-01-10 00:00:00    3     999      1   1232.16

13  1660 1998-01-10 00:00:00    3     999      1   1232.16

13  1762 1998-01-10 00:00:00    3     999      1   1232.16

13  1843 1998-01-10 00:00:00    3     999      1   1232.16

13  4663 1998-01-10 00:00:00    3     999      1   1232.16

13  2273 1998-01-10 00:00:00    3     999      1   1232.16

13  2380 1998-01-10 00:00:00    3     999      1   1232.16

13  2683 1998-01-10 00:00:00    3     999      1   1232.16

13  2865 1998-01-10 00:00:00    3     999      1   1232.16

13  1948 1998-01-10 00:00:00    3     999      1   1232.16

10 rows selected.

这是因为对where的处理会先于order by。因此这个查询将获取它最先发现的10条记录,然后对它们进行排序。这样的结果不是真正的前10.

下面的查询更好:

SELECT /* top10_subquery */

*

FROM (SELECT cust_id, prod_id, time_id, amount_sold

FROM sales

ORDER BY amount_sold DESC)

WHERE rownum <= 10;

4    5    6

CUST_ID    PROD_ID TIME_ID    AMOUNT_SOLD

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

3948    18 1999-04-26 00:00:00     1782.72

4150    18 1999-06-26 00:00:00     1782.72

40    18 1999-06-26 00:00:00     1782.72

33724    18 1999-06-21 00:00:00     1782.72

32863    18 1999-06-21 00:00:00     1782.72

31364    18 1999-06-21 00:00:00     1782.72

10864    18 1999-06-21 00:00:00     1782.72

10620    18 1999-06-21 00:00:00     1782.72

6490    18 1999-06-21 00:00:00     1782.72

4788    18 1999-06-21 00:00:00     1782.72

10 rows selected.

oracle如何升序,oracle排序操作相关推荐

  1. oracle查询的默认排序,oracle 默认排序及认知

    Oracle对无orderby的语句返回的结果不进行排序,oracle此时的处理方式是按照数据的物理存储顺序来读取数据.因为rowid是每行数据的地址,所以有时候看起来会像是使用rowid排序的.但这 ...

  2. oracle根据null排序,oracle 关于null值排序

    在oracle中根据字段来desc排序的话null值可能会在数据的最前面.然而有时候我们查看数据的时候并不希望能够在前面看到这些null值的排序数据. 因此我查了一下: 1.排序的时候运用nvl(). ...

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

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

  4. oracle 分组 排名,Oracle数据库之分组查询及排序

    分组查询:使用 group by 来设置分组,把该列具有相同值的多条记录当成一组记录来处理,然后只会输出一条记录,得到的结果会默认使用升序的方式进行排列. 规则: (1)如果使用了分组函数,或者是 g ...

  5. oracle不属于集合操作,Oracle的几个集合操作

    Oracle的几个集合操作 Union,对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序: Union All,对两个结果集进行并集操作,包括重复行,不进行排序: Intersect,对 ...

  6. Oracle从零开始5——数据库定义操作

    5.1 创建和管理表 在Oracle中之前使用emp.dept等都是系统内建好的表,在SQL语法只能够同样支持了表的创建语句,要想创建表,则应该首先了解Oracle中最常使用到的几种数据类型 1)常用 ...

  7. oracle排序字符,Oracle数据字符集和排序的用法

    以下的文章主要是介绍Oracle数据字符集与排序,以下的文章是对Oracle数据字符集与排序进行了实际操作,由此来详细说明在Oracle数据库中的相关字符集与相关排序的某些命令,特此整理出来,以备后用 ...

  8. ORACLE 正负数分开排序 SQL

    ORACLE 正负数分开排序 SQL 表结构 create table TEST_ORDER (t_name VARCHAR2(5),t_value NUMBER(3) ); 表数据 insert i ...

  9. oracle 汉字和英文排序,关于oracle对汉字的排序

    最近项目过程中碰到对于数据进行排序按照升序排序需求.这需求貌似很简单,我没多想直接order by columnName.忽略了汉字排序的问题导致bug的出现. 业务要求,按照excel中排序出来的结 ...

最新文章

  1. 至强® 平台配备先进遥测技术让您的数据中心更智能
  2. jquery easyui datagrid使用参考
  3. LANGUAGE MODELS ARE OPEN KNOWLEDGE GRAPHS —— 读后总结
  4. .sql文件如何执行_随手记 02 日志系统:一条SQL更新语句是如何执行的?
  5. resnet模型的图像分类结构图_ResNet - 2015年 ILSVRC 的赢家(图像分类,定位及检测)...
  6. 如何在CentOS 7上安装和使用PostgreSQL
  7. 支撑位和压力位怎么看是什么意思?
  8. 已解决——pycharm在同目录下import,pycharm会提示错误,但是可以运行
  9. iOS开发sourceTree提交和拉取代码的时候每次输入密码解决
  10. qqxml代码-班级作业xml卡片代码班级作业
  11. mysql where 小于_MySQL-过滤数据(WHERE语句)
  12. html中的==$0是什么意思
  13. SCAFFOLD: Stochastic Controlled Averaging for Federated Learning
  14. 【技能】使用纯CSS+html写出方向箭头,简单大方,好看
  15. 在线预览 Word、Excel、PowerPoint 文档——Office Online插件使用
  16. 使用beautifulSoup
  17. http劫持软件、怎么应对这样的 HTTP 劫持
  18. 嵌入式Linux--U-Boot(三)Boot命令使用
  19. 小学生长度、面积、时间、质量单位换算总结
  20. cmpp2.0 php,174短信发送状态回执错误码、返回值信息、错误原因

热门文章

  1. CRNN维度变换的解释这样你也可以自定义CRNN了
  2. python for循环习题
  3. 死磕 java同步系列之ReentrantReadWriteLock源码解析
  4. JDK8 stream toMap() java.lang.IllegalStateException: Duplicate key异常解决(key重复)
  5. windows service自动启动相关设置
  6. Dataguard failover切换应用redo操作
  7. iPhone地图 实战iPhone GPS定位系统
  8. virtualbox在装centos5.6时自协把virtualbox add-on 装上了
  9. 大数据笔记2019.5.10
  10. Spark快速上手-WordCount案例