2016-04-26 8 views
3

ich eine Abfrage haben, die zwei Reihen holt -DESC auf gleiche Werte geändert plötzlich

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 

Nun ist diese in dieser Form führen bisher verwendeten

+------+-------+------+------------+-----------+---------+------------------+ 
| 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 | 
+------+-------+------+------------+-----------+---------+------------------+ 

Kürzlich bemerkte ich die Ausgabe nun wie folgt ist (6 oberhalb und unterhalb 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 | 
+------+-------+------+------------+-----------+---------+------------------+ 

Wenn ich die ORDER BY-Klausel tb.type entfernen . Das Ergebnis ist wieder normal (4 an der Spitze zu sein)

Verwirrung-
1. Warum/Wie kam es plötzlich verändert?
2. Obwohl tb.type gleich ist, d. H. TYPE='N', warum sortiert/sortiert die Datenbank? Da beide Werte gleich sind, sollte keine Bestellung stattfinden, oder?

* EDIT - Wenn ich tb.type entfernen, die Art ist wieder normal. Aber wenn ich es zurückstelle, setzt die Sorte 6 an die Spitze. *

Dies bedeutet, dass die Sortierung nicht beliebig ist.

Meine Analyse - der Regel so, wie es in indizierte Struktur gespeichert wird verwendet, wenn zwei Werte gleich sind. Aber das letzte DDL-Datum (Neuerstellungsdatum) für den Index ist das Jahr 2015. Dies bedeutet, dass der Index immer noch derselbe ist.

Jede Idee, warum dies geschieht?

+0

Ist das 'last_analyzed' Datum in' user_tables' oder 'user_indexes' die Zeit, das Verhalten geändert zu reflektieren? Ich kann mir vorstellen, dass Oracle eine Analyse durchgeführt hat, die den Ausführungsplan geändert hat (aufgrund der Aktualisierung der Statistiken). Es könnte sich lohnen, den Ausführungsplan für die Abfrage jetzt mit und ohne die 'tb.type'-Reihenfolge zu betrachten, und wenn Sie den Plan abrufen können, der vor der Änderung für die echte Abfrage verwendet wurde. Aber letztendlich waren Sie 'glücklich', das Ergebnis zu erhalten, das Sie bisher erwartet haben; Gordon hat Recht, die Reihenfolge der Ergebnisse ist unbestimmt, dann sind Typ und Wert gleich. –

+0

Siehe auch: [Order in the court!] (Http://tkyte.blogspot.co.uk/2005/08/order-in-court.html) für Tom Kytes viel zitierte Abhandlung zu diesem Thema. –

+0

@AlexPoole Das last_analyzed ist das Datum von gestern. Es analysiert alle 7 Tage, schätze ich. –

Antwort

3

SQL im Allgemeinen - und Oracle insbesondere - nicht implementieren stabile Sorten. Eine stabile Sortierung ist eine, die die ursprüngliche Reihenfolge der Datensätze beibehält.

SQL-Tabellen und Ergebnisse Sätze haben keine inhärente Reihenfolge. Wenn Sie Stabilität wünschen, müssen die Tasten in order by (in Kombination) unabhängig von einer Indexierung auf dem Tisch eindeutig sein.

+0

Es ist seit etwa 7 Jahren gleich. Du meinst zu sagen, dass es eine willkürliche Bestellung von den letzten 7 Jahren war und jetzt änderte es sich plötzlich wegen instabiler Art oder Orakel? –

+1

Bis Oracle 10g verwendete Oracle häufig eine Abfragestrategie, die konsistente Sortergebnisse für Spalten lieferte, die nicht in der Order by-Klausel enthalten waren. Aber die Dokumentation war immer korrekt. –

+2

@PirateX - die Reihenfolge der Ergebnismenge ist seit sieben Jahren unbestimmt, ja; die "plötzliche Änderung" könnte darauf zurückzuführen sein, dass der Optimierer aufgrund von Daten oder Statistiken auf der letzten harten Analyse etwas anderes getan hat; oder nur die Bestelldatenblöcke werden für diese bestimmten Zeilen abgerufen. –

1

Die Dokumentation eindeutig fest, dass
https://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_10002.htm

order_by_clause

Verwenden Sie die ORDER BY-Klausel von der Anweisung zurückgegebenen Zeilen zu bestellen. Ohne order_by_clause besteht keine Garantie, dass die gleiche Abfrage mehr ausgeführt als einmal Zeilen in der gleichen Reihenfolge abgerufen werden.


  1. Warum/Wie kam es plötzlich verändert?

Da die Datenbank alternativen Zugriffspfad als vorheriger choosed, höchstwahrscheinlich aufgrund einer Tabelle Wachstum, eine Statistik zu aktualisieren, oder weil einiger Index erstellt wurde oder fallen gelassen.

Bitte nehmen Sie sich einen Blick auf die folgende einfache Beispiel:

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 

Und nun die gleichen Daten, aber ein Index erstellt wird:

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 

Im ersten Fall wird die Datenbank verwendet ein vollständiger Tabellenscan
Im zweiten Fall verwendet die Datenbank einen Index (unterschiedlicher Zugriffspfad) und Reihen bestellen ist anders - aber in beiden Fällen trifft es eine Anforderung in der Abfrage angegeben order by object_type


Wenn die Daten sortiert werden auch durch Newdays Spalten, verwenden Sie einfach:

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