In Ihrer Frage gibt es eine implizite Annahme, dass eine relationale Datenbanktabelle irgendwie geordnet ist. Es ist nicht. Es stellt einen Satz dar. Mengen sind per Definition ungeordnet (z. B. ist die Menge [a, b, c] dieselbe Menge wie [b, c, a]).
Daher garantiert SQL ausdrücklich keine bestimmte Reihenfolge für eine Ergebnismenge, es sei denn, eine wird über eine ORDER BY-Klausel angegeben. Die Ausführung genau derselben Abfrage ohne ORDER BY zweimal hintereinander könnte theoretisch identische Ergebnismengen mit unterschiedlicher Reihenfolge zurückgeben (zum Beispiel könnten bestimmte Seiten der Tabelle bereits im Cache sein und überprüft werden, bevor die Ausführungsmaschine andere Seiten betrachtet). In der Praxis wird ein Clustering-Index für die Tabelle (in SQL Server) zurückgegeben, wenn die Ergebnisse in Clustersequenz (sofern die Abfrage den Clusterindex oder Nicht-Index verwendet) als Nettoeffekt des Hinzufügens eines Clusterindex zurückgegeben werden ist, die Datenseiten der Tabelle zu den Blattknoten des B-Baums zu machen, der der Clusterindex ist. Ohne einen Clustering-Index befinden sich die Datenseiten der Tabelle in einem Heap, und jeder (nicht geclusterte) Index ist ein B-Baum, bei dem die Blattknoten Zeiger auf eine Datenseite im Heap sind.
Zurück zu Ihrer Frage ...
Betrachten Sie die Tabelle:
create table dbo.PublicFile
(
id int not null ,
name varchar(500) not null ,
access_cnt int not null ,
dt_last_access datetime not null ,
primary key nonclustered (id) ,
unique nonclustered (name) ,
)
Die beiden Spalten access_cnt und dt_last_access sind von Ihrer Beschreibung hochdynamischen beide. Jeder Zugriff auf eine Datei führt zu einer Aktualisierung dieser beiden Spalten.Wenn Sie einen Clustering-Index auf diese setzen, treten Performance-Probleme aufgrund der hohen Anzahl von Seitenaufteilungen auf, die auftreten, wenn Zeilen im Index verschoben werden. (Sie haben das gleiche Problem mit einem nicht gruppierten Index, aber die Seitenaufteilung betrifft nur die Indexseiten, nicht die Datenseiten, eine viel kleinere Spalte.)
Zuerst schreiben Sie die Abfrage an Erhalten Sie die gewünschten Ergebnisse ohne Berücksichtigung der Indizierung (das ist eine Optimierung). Diese Abfrage wird Ihnen die Liste der öffentlichen Dateien in den letzten 7 Tagen zugegriffen wird, durch die Anzahl der Zugriffe in absteigender Reihenfolge geordnet:
select *
from dbo.PublicFile f
where f.dt_last_access >= dateadd(day,-7,current_timestamp)
order by f.access_cnt desc , f.name
Je nach Größe der Daten, könnte dies auch Server, wie es steht. Wenn Sie 4 oder 5 Millionen Zeilen haben, wird es wahrscheinlich nicht. Ihr DBA wird wahrscheinlich einen Index für die Daten des letzten Zugriffs und die Zugriffsanzahl hinzufügen. Ich würde wahrscheinlich nur einen Index verwenden:
create nonclustered index PublicFile_IX01
on dbo.PublicFile (dt_last_access ,
access_cnt desc
)
Aber es gibt eine gewisse Menge an Experimenten beteiligt. Abhängig von der Semantik der Abfrage und der Form der Daten mag der Abfrageoptimierer sie mögen oder auch nicht.
Es gibt * keine * Garantie, dass die * physische * Reihenfolge der Zeilen in der Datenbankdatei der Reihenfolge entspricht, die durch den gruppierten Index definiert wurde. Alles, was ein Clustered-Index garantiert, ist, dass Bereichsabfragen, die für dieselben Spalten wie die im Clustered-Index aufgeführten ausgedrückt werden, mit weniger Suchvorgängen als mit einem Nicht-Clustered-Index erfüllt werden können. Aber Sie haben richtig zu sagen, immer eine ORDER BY-Klausel anzugeben. –
@Damien_The_Unbeliever: Mein Verständnis war mit einem gruppierten Index, Datensätze innerhalb einer einzelnen Seite würde durch den Cluster-Schlüssel geordnet werden. Der Nettoeffekt besteht darin, dass, während sich einzelne Seiten nicht in einer bestimmten Reihenfolge auf der Platte befinden, die Kosten für das Sortieren von Datensätzen etwas verringert werden (es wird effektiv zu einer Zusammenführungs-Sortieroperation). Aber vielleicht habe ich etwas falsch verstanden. – LBushkin