Pada Apa Titik Apakah Memiliki Indeks Menjadi Efisien

9

Saya telah menemukan banyak sumber yang menyebutkan bahwa menambahkan indeks ke tabel membuat pencarian lebih cepat dan memasukkan lebih lambat, tetapi hanya jika tabelnya besar. Ini menciptakan tradeoff, yang merupakan keputusan desain, tetapi harus ada perkiraan ukuran tabel sebelum menggunakan indeks tidak masuk akal. (10 baris, misalnya, mungkin jauh di bawah batas itu)

Apakah ada yang tahu tentang di mana batas ini berada, atau tahu sumber daya yang akan mengarahkan saya ke arah yang benar?

SeanVDH
sumber
Berapa rasio baca / tulis untuk aplikasi Anda? Jika Anda benar-benar menulis intensif, maka mungkin itu adalah titik di mana Anda perlu mempertimbangkan tradeoff menulis, tetapi jika itu adalah aplikasi biasa, saya akan menambahkan indeks yang diperlukan dalam 99% kasus (tabel biasanya tumbuh, mereka hampir tidak kembali ke ukuran).
Marian

Jawaban:

12

Batas tepat sangat sulit untuk ditentukan sebelumnya.

Satu hal yang diremehkan kebanyakan orang adalah persyaratan tinggi yang harus dipenuhi indeks, sebelum menjadi kandidat untuk digunakan dalam kueri.

Indeks yang efisien (tidak tercakup)

  • menawarkan selektivitas yang baik , misalnya mengembalikan hanya persentase yang sangat kecil (<1%, <2%) dari total baris. Jika selektivitas tidak diberikan - pengoptimal permintaan SQL Server kemungkinan besar akan mengabaikan indeks ini

  • idealnya harus mencakup permintaan, yaitu mengembalikan semua kolom yang diperlukan oleh permintaan. Jika Anda dapat membuat indeks yang memiliki 1 atau 2 kolom indeks, dan menyertakan beberapa kolom lainnya (2-4) sebagai kolom yang disertakan dan dengan demikian Anda dapat menutup kueri - maka kemungkinan pengoptimal kueri akan menggunakan indeks ini. Yang juga berarti: jika kode Anda selalu digunakan SELECT * .....untuk mengambil semua kolom , kemungkinan indeks yang digunakan turun - cukup dramatis, sebenarnya

Saya yakin ada banyak kriteria lain juga - tetapi saya percaya kedua kriteria ini adalah yang paling kritis. Tentu saja, Anda harus selalu menjaga indeks Anda terjaga dengan baik (mengatur ulang, membangun kembali) dan memastikan statistik yang terkait dengan indeks Anda tetap terbaru.

PS: indeks nonclustered pada kolom kunci asing adalah kasus khusus; secara default, saya selalu merekomendasikan untuk menambahkannya, karena mereka membantu mempercepat kedua pemeriksaan integritas referensial, dan juga JOINpada kendala FK tersebut. Tetapi bahkan di sini, itu benar-benar valid untuk "memperluas" indeks kolom FK dengan menambahkan beberapa kolom "termasuk" tambahan untuk membuatnya lebih berguna.

marc_s
sumber
2
Meskipun jawaban ini mungkin tidak secara langsung menjawab pertanyaan, itu jauh lebih baik dengan memberikan prinsip-prinsip desain penting untuk indeks, dan menjawab pertanyaan yang seharusnya saya tanyakan di tempat pertama.
SeanVDH
6

Anda mungkin melihat peningkatan dari indeks dengan hanya 10 baris.

Dalam pengujian berikut pada komputer saya versi tanpa indeks selesai dalam 10.5hitungan detik dan versi dengan indeks dalam 9.8detik (konsisten lebih dari 3 berjalan).

Indeks dalam hal ini hanya terdiri dari 1 halaman daun tetapi karena susunan slot dipesan dalam urutan kunci indeks, kehadirannya memungkinkan SQL Server untuk hanya mengembalikan satu baris minat daripada melakukan agregasi pada semua 10.

CREATE TABLE T
(
X INT,
Y CHAR(100) NULL
)

INSERT INTO T (X)
SELECT number 
FROM master..spt_values
WHERE type='P' AND number BETWEEN 1 AND 10

set nocount on;

DECLARE @I INT, @X INT

DECLARE @Time DATETIME2(7) = SYSUTCDATETIME()

SET @I = 1
    WHILE (@I < 1000000)
    BEGIN
    SELECT @X = MAX(X)
    FROM T
    SET @I += 1
    END

SELECT DATEDIFF(MICROSECOND, @Time, SYSUTCDATETIME())

CREATE CLUSTERED INDEX IX ON T(X)
SET @Time = SYSUTCDATETIME()
SET @I = 1
    WHILE (@I < 1000000)
    BEGIN
    SELECT @X = MAX(X)
    FROM T
    SET @I += 1
    END

SELECT DATEDIFF(MICROSECOND, @Time, SYSUTCDATETIME())

DROP TABLE T
Martin Smith
sumber
Apakah sisipan terpengaruh sama, atau apakah perlambatan minimal?
SeanVDH
@SeanVDH - Contoh dalam jawaban saya adalah membandingkan indeks berkerumun ke tumpukan. Akan masuk akal bahwa menyisipkan antara baris yang ada akan lebih lambat karena baris harus pergi ke tempat tertentu dan array slot ditulis ulang juga kemungkinan pemisahan halaman. Untuk sisipan yang lebih besar data dapat diurutkan ke dalam urutan kunci CI juga yang tidak perlu saat memasukkan ke tumpukan. Kimberley Tripp berpendapat di sini bahwa kadang-kadang memasukkan ke CI bisa lebih baik daripada memasukkan ke tumpukan.
Martin Smith
Terima kasih atas artikelnya, dia menyajikan beberapa poin menarik. Saya bertanya-tanya apakah sisipan akan terpengaruh secara dramatis seperti pilihan di meja kecil, tapi Anda benar, pengorbanannya harus sama di awal seperti nanti.
SeanVDH