Dengan asumsi kolom diindeks berikut ini harus cukup efisien.
Dengan dua upaya 10 baris dan kemudian semacam (hingga) 20 dikembalikan.
WITH CTE
AS ((SELECT TOP 10 *
FROM YourTable
WHERE YourCol > 32
ORDER BY YourCol ASC)
UNION ALL
(SELECT TOP 10 *
FROM YourTable
WHERE YourCol <= 32
ORDER BY YourCol DESC))
SELECT TOP 10 *
FROM CTE
ORDER BY ABS(YourCol - 32) ASC
(yaitu berpotensi seperti di bawah ini)
Atau kemungkinan lain (yang mengurangi jumlah baris yang diurutkan hingga maks 10)
WITH A
AS (SELECT TOP 10 *,
YourCol - 32 AS Diff
FROM YourTable
WHERE YourCol > 32
ORDER BY Diff ASC, YourCol ASC),
B
AS (SELECT TOP 10 *,
32 - YourCol AS Diff
FROM YourTable
WHERE YourCol <= 32
ORDER BY YourCol DESC),
AB
AS (SELECT *
FROM A
UNION ALL
SELECT *
FROM B)
SELECT TOP 10 *
FROM AB
ORDER BY Diff ASC
NB: Rencana eksekusi di atas adalah untuk definisi tabel sederhana
CREATE TABLE [dbo].[YourTable](
[YourCol] [int] NOT NULL CONSTRAINT [SomeIndex] PRIMARY KEY CLUSTERED
)
Secara teknis, Sortir di cabang bawah tidak boleh diperlukan karena itu juga dipesan oleh Diff, dan dimungkinkan untuk menggabungkan dua hasil yang dipesan. Tetapi saya tidak bisa mendapatkan rencana itu.
Kueri memiliki ORDER BY Diff ASC, YourCol ASC
dan bukan adil ORDER BY YourCol ASC
, karena itulah yang akhirnya berfungsi untuk menyingkirkan Urutan di cabang teratas paket. Saya perlu menambahkan kolom sekunder di (meskipun itu tidak akan pernah mengubah hasilnya karena YourCol
akan sama untuk semua nilai dengan Diff yang sama) sehingga akan melalui gabungan gabungan (penggabungan) tanpa menambahkan Sort.
SQL Server tampaknya dapat menyimpulkan bahwa indeks pada X yang dicari dalam urutan naik akan menghasilkan baris yang dipesan oleh X + Y dan tidak diperlukan jenis. Tetapi tidak dapat menyimpulkan bahwa bepergian indeks dalam urutan menurun akan menghasilkan baris dalam urutan yang sama dengan YX (atau bahkan hanya unary minus X). Kedua cabang rencana menggunakan indeks untuk menghindari pengurutan, tetapi TOP 10
di cabang bawah kemudian diurutkan berdasarkan Diff
(meskipun mereka sudah dalam urutan itu) untuk mendapatkannya dalam urutan yang diinginkan untuk penggabungan.
Untuk definisi kueri / tabel lainnya, mungkin lebih sulit atau tidak mungkin untuk mendapatkan rencana penggabungan hanya dengan semacam cabang - karena bergantung pada menemukan ekspresi pemesanan yang SQL Server:
- Menerima bahwa pencarian indeks akan memasok pesanan yang ditentukan sehingga tidak diperlukan penyortiran sebelum bagian atas.
- Dengan senang hati digunakan dalam operasi gabungan sehingga tidak memerlukan pengurutan setelah
TOP
SELECT TOP 10 * FROM YourTable ORDER BY ABS(YourCol - 32) ;
Bahkan lebih sederhana. Juga tidak efisien.