Apa yang dimaksud dengan "indeks" pada RDBMS? [Tutup]

21

Saya menggunakan indeks seperti yang dilakukan kebanyakan pengembang (kebanyakan pada ... indeks!), Tapi saya yakin ada banyak cara halus untuk mengoptimalkan database menggunakan indeks. Saya tidak yakin apakah ini khusus untuk implementasi DBMS apa pun.

Pertanyaan saya adalah: apa contoh yang baik tentang bagaimana menggunakan indeks (kecuali untuk kasus dasar, jelas), dan bagaimana DBMS mengoptimalkan database ketika Anda menentukan indeks pada tabel?

Thomas Joulin
sumber
Dalam memikirkan lebih lanjut pertanyaan ini, pertanyaan ini terlalu umum untuk situs ini. Jika kami mengubah ruang lingkup pertanyaan yang mungkin sesuai, jika tidak pertanyaan ini tidak sesuai untuk situs.
jcolebrand
Saya ingin menjelaskan indeks menggunakan metafora perpustakaan mysqlperformanceblog.com/2011/08/30/... Lihat jika itu membantu ..
Jonathan

Jawaban:

11

Pikirkan indeks sebagai "daftar isi" ... yang merupakan daftar petunjuk pointer ke posisi dalam file, alias offset. Katakanlah Anda memiliki jutaan catatan yang disimpan dalam sebuah tabel, daripada mencari tabel untuk kriteria yang cocok, itu jauh lebih cepat untuk merujuk daftar yang sesuai dengan daftar, kemudian menumpuk pointer ke baris yang cocok. Contoh indeks yang sempurna adalah bidang kunci utama tabel, biasanya bidang "id" -nya. Jika Anda ingin id baris # 11234566, itu jauh lebih cepat meminta indeks untuk pointer ke data daripada memindai sumber data untuk posisi 11234566.

Inilah penggunaan pengindeksan yang tidak begitu jelas:

CREATE TABLE activity_log (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
activity_type_id SMALLINT UNSIGNED NOT NULL,
datetime_created DATETIME
KEY(activity_type_id),
PRIMARY KEY(id)
);
CREATE TABLE activity_log_to_date_key (
activity_log_id INT UNSIGNED NOT NULL,
date_created_key  INT UNSIGNED NOT NULL REFERENCES dim_datetime(id),
UNIQUE KEY(activity_log_id),
KEY(date_created_key)
);
CREATE TABLE dim_datetime (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
date_hour DATETIME NOT NULL,
PRIMARY KEY(id),
KEY(date_hour)
);

Operasi Anda dapat membuat catatan log Anda, tetapi kemudian membuat referensi ke waktu indeks yang lebih cepat untuk mencari / mengurutkan dari tabel log Anda. Kemudian gabungkan kembali tabel log Anda dengan kunci utama sendiri. Jika Anda membutuhkan saya untuk memperluas ini, beri tahu saya. Saya harap ini masuk akal.

Permintaan sampel:

SELECT a.activity_log_id, al.activity_type_id, al.datetime_created
FROM activity_log_to_date_key a 
INNER JOIN dim_datetime d ON (d.id = a.date_created_key)
LEFT JOIN activity_log al ON (al.id = a.activity_log_id)
WHERE d.date_hour BETWEEN '2009-01-01 00:00:00' AND '2009-06-01 12:00:00';
randomx
sumber
terima kasih, itu sangat jelas! Dalam contoh Anda, apakah "PRIMARY" akan mengubah cara RDMBS menyimpan "offset", atau hanya digunakan untuk kendala keunikan?
Thomas Joulin
9

Satu hal yang sepertinya dilewatkan oleh banyak orang adalah bahwa DBMS akan sering (atau hanya dapat) hanya menggunakan satu indeks per tabel referensi dalam kueri, dan jika dapat dan memang menggunakan beberapa indeks, mungkin akan lebih cepat untuk menggunakan gabungan indeks jika ada.

Misalnya, jika mencari tabel besar untuk baris WHERE AnIntegerColumn = 42 AND AnOtherInt = 69, rute tercepat ke baris itu akan menjadi indeks pada dua kolom AnIntegerColumn dan AnOtherInt. Jika Anda hanya memiliki indeks pada masing-masing secara individual tetapi tidak ada indeks gabungan, DB akan mencari satu atau yang lain indeks dan secara terpisah menyaring hasil dengan klausa kedua, atau memindai keduanya dan mengawinkan hasilnya setelah itu.

Operasi sederhana umum lainnya yang dapat ditingkatkan dengan indeks komposit adalah WHERE SomeColumn = <SomeValue> ORDER BY SomeOtherColumn- jika ada indeks pada SomeColumn dan SomeOtherColumn (dalam urutan yang benar) operasi penyaringan dan pemesanan dapat dilakukan pada waktu yang sama dalam beberapa keadaan.

Menambahkan terlalu banyak indeks tentu saja bisa menjadi optimasi yang buruk, karena ruang tambahan yang digunakan untuk menyimpan indeks (dan beban-IO untuk mempertahankannya jika DB Anda melihat banyak operasi penulisan) mungkin merupakan masalah yang lebih buruk daripada kueri baca yang sedikit kurang optimal , jadi jangan berlebihan.

David Spillett
sumber
2

David dan Randy sudah membahas hal ini. Saya hanya ingin menambahkan bahwa para EXPLAINperintah dapat menjadi bantuan besar dalam mencari tahu ketika Anda akan mendapatkan besar penghematan dari membuat indeks, serta menyarankan indeks yang dibutuhkan. Ini akan menampilkan langkah-langkah yang diambil oleh database untuk menjalankan kueri Anda, sehingga Anda tahu bit mana yang paling lama.

Gaurav
sumber
Untuk menambah jawaban Gaurav, gunakan "EXPLAIN EXTENDED", lalu segera ketik "SHOW WARNINGS" untuk melihat bagaimana pertanyaan Anda diterjemahkan.
randomx
1

Sesuatu yang belum saya lihat disebutkan di sini adalah bahwa ketika Anda memiliki lebih dari satu disk Anda mungkin ingin meletakkan indeks Anda pada disk yang berbeda dari tempat data sebenarnya berada. Ini dapat mempercepat beberapa operasi. Saya pikir ini pantas ditanyakan sendiri.

jcolebrand
sumber
Itu dulu benar tetapi hari ini kami katakan jangan mencoba menebak-nebak subsistem I / O Anda. Anda tidak tahu di mana array penyimpanan akan menempatkan data Anda.
Gayus
1
@gaius Saya lebih suka jika Anda tidak memiliki setup RAID5 (atau sejenisnya), untuk menempatkan indeks pada E :, data pada F :, dll.
jcolebrand