Nie będzie żadnych różnic, ponieważ możesz sprawdzić się, sprawdzając plany wykonania. Jeśli id
jest indeksem klastrowym, powinieneś zobaczyć uporządkowany skany indeksu klastra; jeśli nie jest zindeksowane, nadal będzie można wyświetlić skanowanie tabeli lub sklasyfikowany indeks, ale nie zostanie on zamówiony w obu przypadkach.
Podejście TOP 1
może być przydatne, jeśli chcesz przeciągnąć inne wartości z wiersza, co jest łatwiejsze niż ciągnięcie maksimum w podzapytaniu, a następnie dołączanie. Jeśli chcesz inne wartości z rzędu, musisz dyktować, jak radzić sobie z więzami w obu przypadkach.
Po tym, istnieją pewne scenariusze, w których plan może się różnić, dlatego ważne jest, aby przetestować w zależności od tego, czy kolumna jest indeksowana i czy monotonicznie rośnie. Utworzony prostego stołu i dodaje 50000 wierszy:
CREATE TABLE dbo.x
(
a INT, b INT, c INT, d INT,
e DATETIME, f DATETIME, g DATETIME, h DATETIME
);
CREATE UNIQUE CLUSTERED INDEX a ON dbo.x(a);
CREATE INDEX b ON dbo.x(b)
CREATE INDEX e ON dbo.x(e);
CREATE INDEX f ON dbo.x(f);
INSERT dbo.x(a, b, c, d, e, f, g, h)
SELECT
n.rn, -- ints monotonically increasing
n.a, -- ints in random order
n.rn,
n.a,
DATEADD(DAY, n.rn/100, '20100101'), -- dates monotonically increasing
DATEADD(DAY, -n.a % 1000, '20120101'), -- dates in random order
DATEADD(DAY, n.rn/100, '20100101'),
DATEADD(DAY, -n.a % 1000, '20120101')
FROM
(
SELECT TOP (50000)
(ABS(s1.[object_id]) % 10000) + 1,
rn = ROW_NUMBER() OVER (ORDER BY s2.[object_id])
FROM sys.all_objects AS s1
CROSS JOIN sys.all_objects AS s2
) AS n(a,rn);
GO
w systemie Spowodowało to wartości w/c od 1 do 50000, b/d między 3 a 9994 E/G z 2010-01-01 przez 2011-05-16, i f/h od 2009-04-28 do 2012-01-01.
Najpierw porównajmy indeksowane monotonicznie rosnące kolumny całkowite a i c. A ma indeksu klastrowego, c nie:
SELECT MAX(a) FROM dbo.x;
SELECT TOP (1) a FROM dbo.x ORDER BY a DESC;
SELECT MAX(c) FROM dbo.x;
SELECT TOP (1) c FROM dbo.x ORDER BY c DESC;
Wyniki:
Duży problem z 4. zapytania jest to, że w przeciwieństwie do MAX
, to wymaga pewnego rodzaju. Tutaj 3 w porównaniu do 4:
będzie to powszechny problem we wszystkich tych odmianach zapytania: a MAX
na kolumnie niezindeksowane będzie mógł świnka powrotem na klastrze indeksuj skanuj i wykonuj agregację strumieniową, podczas gdy TOP 1
musi wykonać sortowanie, które będzie droższe.
Zrobiłem test i zobaczyłem dokładnie takie same wyniki w testach b + d, e + g i f + h.
Wydaje mi się, że oprócz generowania większej ilości kodów zgodności z normami, istnieje potencjalne korzyści związane z używaniem MAX
na rzecz TOP 1
w zależności od tabeli i indeksów (które mogą ulec zmianie po umieszczeniu) twój kod w produkcji). Powiedziałbym więc, że bez dodatkowych informacji preferowane jest ustawienie MAX
.
(I jak powiedziałem wcześniej, TOP 1
może być naprawdę zachowanie jesteś po, jeśli wyciągając dodatkowe kolumny. Będziemy chcieli przetestować MAX
+ JOIN
metod oraz, jeśli to Ty jesteś po.)
Czy to wypróbowałeś? Oczekuję, że będą takie same, jeśli optymalizator jest dobry. – Hogan
Jeśli "id" jest automatycznym inkrementowaniem, to pytanie jest duplikatem http://stackoverflow.com/questions/590079/for-autoincrement-fields-maxid-vs-top-1-id-order-by-id-desc – Ben
id oznacza dowolną kolumnę dowolnego typu. –