相同价值的DESC突然改变

时间:2016-04-26 18:25:11

标签: sql oracle

我有一个获取两行的查询 -

SELECT tb.type,
                tb.value,
                tb.comp,
                tb.start_date,
                tb.end_date,
                tb.newdays,
                tb.modif_date
           FROM table_name tb
          WHERE tb.start_date <= sysdate
            AND tb.end_date >= sysdate
            AND tb.VALUE='ABC'
             ORDER BY tb.value, 
                tb.type DESC

现在这个用来产生这种形式

+------+-------+------+------------+-----------+---------+------------------+
| TYPE | VALUE | COMP | START_DATE | END_DATE  | NEWDAYS |    MODIF_DATE    |
+------+-------+------+------------+-----------+---------+------------------+
| N    | ABC   | **   | 10-Mar-16  | 31-Dec-99 |       4 | 10/03/2016 10:05 |
| N    | ABC   | **   | 07-Mar-16  | 31-Dec-99 |       6 | 07/03/2016 23:23 |
+------+-------+------+------------+-----------+---------+------------------+

最近我注意到输出现在是这样的(6个在上面,4个在下面)

+------+-------+------+------------+-----------+---------+------------------+
| TYPE | VALUE | COMP | START_DATE | END_DATE  | NEWDAYS |    MODIF_DATE    |
+------+-------+------+------------+-----------+---------+------------------+
| N    | ABC   | **   | 07-Mar-16  | 31-Dec-99 |       6 | 07/03/2016 23:23 |
| N    | ABC   | **   | 10-Mar-16  | 31-Dec-99 |       4 | 10/03/2016 10:05 |
+------+-------+------+------------+-----------+---------+------------------+

如果我删除了ORDER BY CLAUSE tb.type。结果再次恢复正常(4位于顶部)

混乱 -
1.为什么/如何突然改变?
2.即使tb.type相等,即TYPE='N',为什么数据库会对它进行排序/排序?由于两个值都相等,因此不应该进行排序,对吧?

*编辑 - 如果我删除tb.type,则排序再次恢复正常。然而,当我把它放回去时,排序将6放在最顶层。 *

  

这意味着排序不是任意的。

我的分析 - 通常,当两个值相等时,使用它存储在索引结构中的方式。但是索引的最后一个DDL日期(重建日期)是在2015年。这意味着索引仍然是相同的。

知道为什么会这样吗?

2 个答案:

答案 0 :(得分:3)

一般的SQL - 特别是Oracle - 不实现稳定的排序。稳定排序是保留记录原始排序的排序。

SQL表和结果集没有固有的顺序。如果您想要稳定性,order by中的键需要(组合)是唯一的,无论表格上是否有任何索引。

答案 1 :(得分:1)

文件明确指出 https://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_10002.htm

  

<强> order_by_clause生成

     

使用ORDER BY子句对语句返回的行进行排序。   如果没有order_by_clause,则不保证存在相同的查询   多次执行将以相同的顺序检索行。

  
      
  1. 为什么/它是如何突然改变的?
  2.   

因为数据库选择了替代访问路径而不是之前的路径,很可能是由于表增长,统计刷新或者因为创建或删除了某些索引。

请看一下以下简单示例:

create table tetest1 as
select t.*, sysdate - dbms_random.value * 10000 as myDate
from all_objects t;
;
select object_id, object_type 
from tetest1
where mydate > sysdate - 2
and object_id between 21000 and 50000
order by object_type;

 OBJECT_ID OBJECT_TYPE           
---------- -----------------------
     47034 JAVA CLASS              
     31660 JAVA CLASS              
     47427 SYNONYM                 
     46113 SYNONYM                 
     26042 SYNONYM                 
     21259 SYNONYM                 
     33351 SYNONYM  

现在相同的数据,但创建了一个索引:

create index my_idx1 on tetest1( mydate );
select object_id, object_type 
from tetest1
where mydate > sysdate - 2
and object_id between 21000 and 50000
order by object_type;

index MY_IDX1 created.
 OBJECT_ID OBJECT_TYPE           
---------- -----------------------
     31660 JAVA CLASS              
     47034 JAVA CLASS              
     26042 SYNONYM                 
     33351 SYNONYM                 
     21259 SYNONYM                 
     47427 SYNONYM                 
     46113 SYNONYM 

在第一种情况下,数据库使用全表扫描 在第二种情况下,数据库使用索引(不同的访问路径),行顺序不同 - 但在这两种情况下,它都满足查询中所述的要求order by object_type

如果您希望按NEWDAYS列对数据进行排序,请使用:

ORDER BY tb.value, 
         tb.type DESC,
         tb.NEWDAYS