Apa arti kata “SARGable”?

23

Pengguna SQL Server menggunakan istilah "sargable" . Saya bertanya-tanya apakah ada definisi abadi agnostik implementasi-agnostik objektif untuk "sargable."

Misalnya, WHERE foo LIKE '%bar%'dikatakan oleh banyak orang tidak murah , tetapi beberapa RDBMS dapat menggunakan indeks pada permintaan tersebut . Apa artinya "tidak mahal" ?

Referensi Lainnya

Evan Carroll
sumber
5
Anda mungkin ingin menunjukkan bahwa pertanyaan Anda bukan tentang SQL Server tetapi tentang istilah " sargable ". Pertanyaan Anda hanya mereferensikan SQL Server karena tidak dapat menangani predikat pencarian "% wordhere%", sedangkan RDBMS yang lain tampaknya.
John aka hot2use

Jawaban:

31

Istilah "sargable" pertama kali diperkenalkan oleh P. Griffiths Selinger et al. dalam makalah mereka tahun 1979 "Jalur Akses Seleksi dalam Sistem Manajemen Database Relasional", yang diterbitkan oleh ACM . Untuk anggota non-ACM ada salinan makalah itu di http://cs.stanford.edu/people/chrismre/cs345/rl/selinger.pdf

Istilah ini didefinisikan dalam paragraf ini:

Baik pemindaian indeks dan segmen 1 dapat secara opsional mengambil seperangkat predikat, yang disebut argumen pencarian (atau SARGS), yang diterapkan pada sebuah tuple sebelum dikembalikan ke pemanggil RSI 2 . Jika tuple memenuhi predikat, itu dikembalikan; jika tidak, pemindaian berlanjut sampai menemukan tuple yang memenuhi SARGS atau menghabiskan segmen atau kisaran nilai indeks yang ditentukan. Ini mengurangi biaya dengan menghilangkan overhead membuat panggilan RSI untuk tupel yang dapat ditolak secara efisien dalam RSS. Tidak semua predikat berbentuk yang bisa menjadi SARGS. Sebuah predikat sargable adalah salah satu bentuk (atau yang dapat dimasukkan ke dalam formulir) "kolom nilai perbandingan-operator". SARGS diekspresikan sebagai ekspresi boolean dari predikat tersebut dalam bentuk normal disjungtif.

Dengan kata lain, predikat sargable adalah sedemikian rupa sehingga dapat diselesaikan oleh mesin penyimpanan (metode akses) dengan secara langsung mengamati tabel atau catatan indeks. Sebaliknya, predikat non-sargable membutuhkan tingkat DBMS yang lebih tinggi untuk mengambil tindakan. Sebagai contoh, hasil dari WHERE lastname = 'Doe'dapat diputuskan oleh mesin penyimpanan dengan hanya melihat isi bidang lastnamesetiap catatan. Di sisi lain, WHERE UPPER(lastname) = 'DOE'memerlukan eksekusi fungsi oleh mesin SQL, yang berarti mesin penyimpanan harus mengembalikan semua baris yang dibacanya (asalkan cocok dengan predikat lain yang mungkin, yang dapat ditagih) kembali ke mesin SQL untuk evaluasi, menimbulkan biaya CPU tambahan .

Anda dapat melihat dari definisi asli bahwa predikat sargable dapat berlaku tidak hanya untuk pemindaian indeks, tetapi juga untuk pemindaian tabel (segmen dalam terminologi Sistem R), selama syarat "perbandingan kolom-nilai operator" terpenuhi dan karenanya dapat dievaluasi oleh mesin penyimpanan. Ini memang kasus dengan Db2, keturunan Sistem R dalam banyak hal :

Predikat sargable indeks tidak digunakan untuk mengelompokkan pencarian, tetapi dievaluasi dari indeks jika dipilih, karena kolom yang terlibat dalam predikat adalah bagian dari kunci indeks. Predikat ini juga dievaluasi oleh manajer indeks.

Predikat sargable data adalah predikat yang tidak dapat dievaluasi oleh manajer indeks, tetapi dapat dievaluasi oleh Layanan Manajemen Data (DMS). Biasanya, predikat ini membutuhkan akses setiap baris dari tabel dasar. Jika perlu, DMS akan mengambil kolom yang diperlukan untuk mengevaluasi predikat,

Fakta bahwa dalam predikat SQL Server-Speak sargable hanya mereka yang dapat diselesaikan menggunakan indeks berusaha mungkin ditentukan oleh ketidakmampuan mesin penyimpanannya untuk menerapkan predikat tersebut selama scan tabel.

Predikat Sargable dan non-sargable kadang-kadang digambarkan sebagai predikat "stage 1" dan "stage 2" (ini juga berasal dari terminologi Db2 ). Predikat tahap 1 dapat dievaluasi pada tingkat terendah dari pemrosesan kueri, saat membaca tabel atau catatan indeks. Baris yang cocok dengan kondisi tahap 1, jika ada, dikirim ke tingkat berikutnya, tahap 2, evaluasi.


1 - Segmen dalam Sistem R adalah penyimpanan fisik tupel tabel; pemindaian segmen agak setara dengan pemindaian tabel di DBMS lainnya.

2 - RSI - RSS 3 Interface, antarmuka permintaan berorientasi tuple. Fungsi antarmuka yang relevan dengan diskusi ini adalah NEXT, yang mengembalikan predikat permintaan pencocokan baris berikutnya.

3 - RSS, atau Research Storage System, subsistem penyimpanan System R.

mustaccio
sumber
"secara langsung mengamati tabel atau catatan indeks" apa artinya itu? Maksud saya tentu saja = UPPER()adalah panggilan fungsi, tetapi begitu juga memcmpdengan sendirinya. Akan relatif mudah untuk menulis memcmpyang mengasumsikan ASCII dan mengabaikan case (lihat saja gigitan kedua). Apakah itu membuatnya TERGANGGU? Lihat juga contoh @ Ypercube, dba.stackexchange.com/questions/162263/…
Evan Carroll
4
@EvanCarroll Berarti melihat tabel atau catatan indeks secara langsung, tanpa bantuan fungsi database yang dilaksanakan di luar mesin penyimpanan (mis. Dalam kueri prosesor / mesin eksekusi / layanan ekspresi). Dalam contoh ypercube, permintaan diproses sebelumnya oleh perencana / pengoptimal sedemikian sehingga pencarian non-SARGable dinyatakan dalam istilah SARGable.
Paul White mengatakan GoFundMonica
Apa yang dimaksud dengan "melihat tabel atau catatan indeks langsung" ? Saya tidak yakin bagaimana itu menjelaskan "langsung mengamati tabel atau catatan indeks" . Apakah x=0SARGable? Bagaimana dengan -0 = +0, ' ' = ''atau kesetaraan spasial? Apa yang akan menjadi contoh dari sesuatu yang SARGable, pasti? Ketika Anda mengatakan "tanpa bantuan fungsi database diimplementasikan di luar mesin penyimpanan" Anda termasuk dalam contoh Ypercube DATE()yang termasuk di dalam mesin penyimpanan. Mengapa itu tidak dapat dilakukan dengan sendirinya?
Evan Carroll
2
@ EvanCarroll Luangkan waktu untuk membaca makalah yang direferensikan, dan mungkin kembali ke jawaban ini setelah itu. Jika Anda masih memiliki pertanyaan yang akan menjadi topik di sini, Anda dapat mengajukannya. Catatan lewat yang DATE()bukan fungsi (SQL Server) nyata, tapi (saya kira) singkatan Mr Cube untuk konversi tipe. Kami juga dapat mendiskusikan hal ini dalam obrolan jika Anda mau.
Paul White mengatakan GoFundMonica
18

Bagi saya, SARGable berarti SQL Server dapat melakukan pencarian indeks menggunakan predikat pencarian Anda.

Anda tidak bisa hanya mengatakan bahwa DBMS dapat "mengambil keuntungan" dari suatu indeks, karena dengan predikat non-sargable, SQL Server dapat akhirnya memindai indeks yang tidak tercakup.

Brent Ozar
sumber
Saya akan memperluas itu untuk eliminasi partisi juga
David itzודו Markovitz
9

Menurut Pro SQL Server Internal oleh Dmitri Korotkevitch :

Predikat ARGument ABLE Search adalah salah satu di mana SQL SERVER dapat memanfaatkan operasi pencarian indeks, jika ada indeks.

Predikat SARGable adalah dimana SQL server dapat mengisolasi nilai tunggal atau rentang nilai kunci indeks untuk diproses

Predikat SARGable termasuk operator berikut: =, >, >=, <, <=, IN, BETWEEN, dan LIKE( dalam kasus pencocokan prefix )

Operator non-SARGable meliputi: NOT, NOT IN, <>, dan LIKE( tidak awalan pencocokan ), serta penggunaan fungsi atau perhitungan terhadap meja, dan jenis konversi di mana datatype tidak memenuhi indeks dibuat.

Contoh :

WHERE name like 'SARGable%'
WHERE name like '%non-SARGable%'

Demo :

DROP TABLE dbo.Testing;
GO

CREATE TABLE Testing (
    WeirdDatatype   int NOT NULL,
    SomethingElse   char(200)
);

CREATE NONCLUSTERED INDEX IDX_ALWAYS_SARGable
    ON dbo.Testing( SomethingElse);

CREATE NONCLUSTERED INDEX IDX_NOT_ALWAYS_SARGable
    ON dbo.Testing(SomethingElse);

INSERT INTO dbo.Testing
        ( WeirdDatatype, SomethingElse )
SELECT TOP 1000 m.message_id, CONVERT(char(200), m.text)
FROM sys.messages AS m;

Sekarang kita jalankan:

SELECT *
FROM dbo.Testing AS t
WHERE  t.WeirdDatatype = 1001;
SELECT *
FROM dbo.Testing AS t
WHERE t.SomethingElse LIKE 'Line%'
SELECT *
FROM dbo.Testing AS t
WHERE t.SomethingElse LIKE '%Line%'
     AND t.WeirdDatatype = 1001;

Hasilnya adalah:

[1]

Mari kita lihat properti dari permintaan SARGable (Index Seek)

masukkan deskripsi gambar di sini

Pengoptimal kueri dapat menentukan batas dalam indeks awal dan akhir. Ini memiliki argumen pencarian untuk ditanyakan.

Sekarang permintaan non-SARGable:

masukkan deskripsi gambar di sini

Anda dapat melihat dengan awal predikat '% non ..%' tidak memungkinkan pengoptimal kueri untuk DEFINE memulai dan mengakhiri atau kisaran dalam indeks. Sekarang harus mencari seluruh tabel (pemindaian).

Vic Work
sumber
Jadi sekali lagi, jika indeks kemudian dibuat yang mendukung, WHERE name like '%non-SARGable%'apakah itu membuat kondisinya lebih baik? Dan, jika demikian, bukankah kita berbicara tentang kelemahan implementasi tertentu? IE., Tidakkah seharusnya kita mengatakan "tidak mahal pada SQL Server 2016"
Evan Carroll
1
Meskipun ada sesuatu yang mungkin dalam rilis SQL Server. Sambil mengingat titik kritis indeks, sebuah wildcard di awal predikat akan sangat sulit bagi pengoptimal kueri untuk menentukan rentang nilai dalam indeks yang dicari. Dengan demikian menggunakan pemindaian dan predikat ini disebut predikat non-SARGable.
Vic Work
2
Tentu saja implementasinya spesifik. WHERE DATE(datetime_column) = '2001-01-01'misalnya adalah "sargable" (akan melakukan pencarian indeks) dalam versi SQL Server yang lebih baru (2008+ saya pikir) tetapi tidak dalam yang lebih lama.
ypercubeᵀᴹ