RANK () ve DENSE_RANK () deterministik mi yoksa deterministik mi?


27

Göre resmi Microsoft BOL DENSE_RANK deterministik olmayan bir ( RANK () ). Ancak Itzik Ben-Gan'ın Sıralama Fonksiyonlarına göre "... RANK () ve DENSE_RANK () fonksiyonları her zaman belirleyicidir". Kim haklı?

Şu ana kadar ne buldum: Microsoft'un Tanımı "Deterministik işlevler, belirli bir giriş değeri kümesiyle çağrıldığında ve veritabanının aynı durumu verildiğinde, her zaman aynı sonucu her zaman döndürür."

Yani Küme teorisi tablolarında Çalışanlar

Employee            Salary
Sue Right            1.00
Robin Page           1.00
Phil Factor          1.00

ve Çalışanlar2

Employee            Salary
Phil Factor          1.00
Sue Right            1.00
Robin Page           1.00

aynıdır. Ancak Sıralama işlevleri farklı değerler döndürür:

    CREATE TABLE [dbo].[Employees](
    --[ID] [int] IDENTITY(1,1) NOT NULL,
    [Employee] [varchar](150) NOT NULL,
    [Salary] [smallmoney] NULL,
) ON [PRIMARY]

GO
CREATE TABLE [dbo].[Employees2](
    --[ID] [int] IDENTITY(1,1) NOT NULL,
    [Employee] [varchar](150) NOT NULL,
    [Salary] [smallmoney] NULL,
) ON [PRIMARY]

INSERT INTO [dbo].[Employees]
([Employee] ,[Salary])
VALUES
('Sue Right', 1)
, ('Robin Page', 1)
,('Phil Factor', 1 )
GO
INSERT INTO [dbo].[Employees2]
([Employee] ,[Salary])
VALUES
('Phil Factor', 1 )
,('Sue Right', 1)
,('Robin Page', 1)
GO
SELECT RANK() OVER ( ORDER BY Salary) AS [Rank]
, DENSE_RANK() OVER (ORDER BY Salary ) AS [Dense_rank]
, [Employee]
FROM
dbo.Employees

SELECT RANK() OVER ( ORDER BY Salary) AS [Rank]
, DENSE_RANK() OVER (ORDER BY Salary ) AS [Dense_rank]
, [Employee]
FROM
dbo.Employees2

SELECT NTILE(3) OVER ( ORDER BY SALARY )
, [Employee]
FROM
dbo.Employees

SELECT NTILE(3) OVER ( ORDER BY SALARY )
, [Employee]
FROM
dbo.Employees2

Yanıtlar:


23

Resmi Microsoft BOL göre DENSE_RANK belirleyici değildir (RANK ()). Ancak Itzik Ben-Gan'ın Sıralama İşlevlerine göre "... RANK () ve DENSE_RANK () işlevleri her zaman belirleyicidir". Kim haklı?

Her ikisi de haklıdır, çünkü “deterministik” kelimesinin farklı duyularını kullanıyorlar.

SQL Server optimizerinin bakış açısına göre "deterministic" çok kesin bir anlama sahip; Ürüne pencere ve sıralama fonksiyonlarından önce gelen bir anlam eklendi. En iyi duruma getiriciye "deterministik" özellik, bir işlevin optimizasyon sırasında iç ağaç yapıları içinde serbestçe kopyalanıp kopyalanmayacağını tanımlar. Bu deterministik olmayan bir işlev için yasal değildir.

Deterministik burada şu anlama gelir: işlevin tam örneği, kaç kez çağrılsa da, aynı giriş için her zaman aynı çıkışı döndürür. Bu, pencereleme işlevleri için asla doğru değildir, çünkü, (tek sıralı) bir skaler işlevi olarak, aynı sonucu bir satır içinde veya satırlar arasında döndürmezler. Basitçe söylemek ROW_NUMBERgerekirse, örnek olarak:

ROW_NUMBERFonksiyonu (tanımı gereği!) Farklı satırlar için farklı değerler döndürür, böylece için optimizasyon amacıyla bu nondeterministic olduğunu

Bu BOL kullandığı anlamda.

Itzik, bir bütün olarak sonucun determinizmi hakkında farklı bir noktaya değiniyor. Sipariş edilen bir giriş setinde (uygun bağlanma ile) çıkış "deterministik" bir sekanstır. Bu geçerli bir gözlem, ancak sorgu optimizasyonu sırasında önemli olan “deterministik” nitelikte değil.


10

NTILE()ilginç bir durum; sıralamadan sonra geçerli gözüküyor (bu, beraberlik durumunda, SQL Server'ın kendi cihazlarına bırakılmış ve bu genellikle sıralama amaçları için en verimli dizin seçimi tarafından yönlendiriliyor). Bunu, SQL Server'ı burada isteğe bağlı bir seçim yapmaya zorlayarak zorlayabilirsiniz - bu OVER()maddeye bir veya daha fazla tie-breaker ekleyin :

OVER (ORDER BY Salary, Employee)

Temel olarak, sıralamayı benzersiz hale getirmeniz gerekir. Aynı ada sahip çalışanlarınız varsa, farklı bir bağ kırıcı sütun seçmeniz veya gerçekten bağ kuruyana kadar sütun eklemeye devam etmeniz gerekebilir.

İçin RANK()ve DENSE_RANK(), kravat o çok önemli bir nedeni aslında edemez farklı değerler olsun. Fonksiyonun çıktısının determinizmini, sonuçların sırasının determinizmiyle karıştırmamaya çalışın. Sorgularınız yoksa ORDER BY, bu konuda belirleyici olmayan ne olabilir?

1   1   Sue Right
1   1   Robin Page
1   1   Phil Factor

1   1   Phil Factor
1   1   Sue Right
1   1   Robin Page

RANK()ve DENSE_RANK()her iki durumda da aynı değerleri uyguladıysanız, SQL Server sonuçları size farklı bir sırayla iade etti. Bunun, aynı çıktıyı aynı girdiden beklemekle RANK()ya DENSE_RANK()da aynı girdiyi vermekle ilgisi yoktur - bu, SQL Server'a (bir ORDER BYmaddeyi ihmal ederek ) sırasını umursamadığınızı söylerken belirleyici bir düzen varsaymak ya da beklemekle ilgilidir . sonuçlar. Burada # 3'e bakınız:


7

Sözdizimi:

WindowFunction() OVER (PARTITION BY <some expressions>        -- partition list
                       ORDER BY <some other expressions>)     -- order list

Her iki fonksiyon RANK()ve DENSE_RANK()tanımlarıyla, OVERmaddede belirtilen ifadelerin kendileri belirleyici olduğu sürece aynı sonuçları üretme garantisi vardır. Ve bu, Itzik Ben-Gun'un makalesinde kastedilen şeydir. Bu listeler en çok ilgili tabloların sadece sütunlarından ibarettir.

Bu nedenle, işlevler genel olarak belirleyici olmamakla birlikte, bunların uygulanması, iki durumu ayırt etmeye ve bölümleme ve sipariş listelerini inceleyerek onları belirleyici ya da değil olarak ele almaya özen göstermiş olabilir.

Vahşi tahminime göre, SQL-Server geliştiricileri, deterministik fonksiyonların tanımlarını bir şekilde çelişmesine rağmen, bunları her zaman “deterministik olmayan” olarak uygulamanın daha kolay olduğuna karar verdiler. Dolayısıyla, MSDN'de deterministik olmayanlar olarak belirtilirler çünkü mevcut uygulamada motor onları daima deterministik olmayanlar olarak kabul eder.

Bir başka argüman, diğer iki pencerenin işlev görmesi ROW_NUMBER()ve NTILE()daha da karmaşık olmalarıdır; çünkü aynı çıktıya sahip oldukları için, listelerdeki bölüm ve sıradaki ifadelerin sadece deterministik değil aynı zamanda benzersiz olmaları da gerekir. Bu yüzden, tüm bu detayları uygulamak önemsiz olmaktan uzak.


Aaron Bertrand'ın cevabında açıkça belirttiği gibi, determinizm ile ilgisi olmadığı için, sonuç kümelerinin sırası hakkında yorum yapmayacağım.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.