@Pierre 303 sudah mengatakannya, tapi aku akan mengatakannya lagi. DO menggunakan indeks pada kombinasi kolom. Indeks gabungan aktif (a, b)
hanya sedikit lebih lambat untuk kueri a
daripada indeks a
sendirian, dan secara besar-besaran lebih baik jika kueri Anda menggabungkan kedua kolom. Beberapa database dapat bergabung indeks pada a
dan b
sebelum memukul meja, tapi ini tidak sebagus memiliki indeks gabungan. Saat Anda membuat indeks gabungan, Anda harus meletakkan kolom yang paling mungkin dicari pertama kali dalam indeks gabungan.
Jika database Anda mendukungnya, DO menempatkan indeks pada fungsi yang muncul dalam permintaan daripada kolom. (Jika Anda memanggil fungsi pada kolom, indeks pada kolom itu tidak berguna.)
Jika Anda menggunakan database dengan tabel sementara benar yang dapat Anda buat dan hancurkan dengan cepat (mis. PostgreSQL, MySQL, tetapi bukan Oracle), maka LAKUKAN membuat indeks pada tabel sementara.
Jika Anda menggunakan database yang memungkinkannya (misalnya Oracle), DO mengunci rencana kueri yang baik. Pengoptimal permintaan dari waktu ke waktu akan mengubah rencana kueri. Mereka biasanya memperbaiki rencana. Tetapi kadang-kadang mereka membuatnya secara dramatis lebih buruk. Anda biasanya tidak akan benar-benar melihat peningkatan rencana - kueri itu bukan hambatan. Tetapi satu rencana buruk dapat menghapus situs yang sibuk.
JANGAN memiliki indeks pada tabel yang akan Anda lakukan memuat data besar. Jauh lebih cepat untuk menjatuhkan indeks, memuat data, lalu membangun kembali indeks daripada mempertahankannya saat Anda memuat tabel.
JANGAN gunakan indeks pada kueri yang harus mengakses lebih dari sebagian kecil dari tabel besar. (Betapa kecilnya tergantung pada perangkat keras. 5% adalah aturan praktis yang layak.) Misalnya, jika Anda memiliki data dengan nama dan jenis kelamin, nama adalah kandidat yang baik untuk pengindeksan karena nama yang diberikan mewakili sebagian kecil dari total baris. Mengindeks gender tidak akan membantu karena Anda masih harus mengakses 50% dari baris. Anda benar-benar ingin menggunakan pemindaian tabel penuh sebagai gantinya. Alasannya adalah bahwa indeks akhirnya mengakses file besar secara acak, menyebabkan Anda perlu mencari disk. Disk berusaha lambat. Sebagai contoh, saya baru-baru ini berhasil mempercepat permintaan selama satu jam yang terlihat seperti:
SELECT small_table.id, SUM(big_table.some_value)
FROM small_table
JOIN big_table
ON big_table.small_table_id = small_table.id
GROUP BY small_table.id
di bawah 3 menit dengan menulis ulang sebagai berikut:
SELECT small_table.id, big_table_summary.summed_value
FROM small_table
JOIN (
SELECT small_table_id, SUM(some_value) as summed_value
FROM big_table
GROUP BY small_table_id
) big_table_summary
ON big_table_summary.small_table_id = small_table.id
yang memaksa database untuk memahami bahwa seharusnya tidak mencoba menggunakan indeks menggoda big_table.small_table_id
. (Basis data yang bagus, seperti Oracle, harus mencari tahu sendiri. Kueri ini berjalan di MySQL.)
Pembaruan: Berikut adalah penjelasan tentang titik pencarian disk yang saya buat. Indeks memberikan pencarian cepat untuk mengatakan di mana data berada di tabel. Ini biasanya menang karena Anda hanya akan melihat data yang perlu Anda lihat. Tetapi tidak selalu, terutama jika Anda pada akhirnya akan melihat banyak data. Disk mengalirkan data dengan baik, tetapi membuat pencarian menjadi lambat. Pencarian acak ke data pada disk membutuhkan 1/200 detik. Versi lambat dari query akhirnya melakukan sesuatu seperti 600.000 dari mereka dan butuh hampir satu jam. (Itu melakukan lebih banyak pencarian daripada itu, tetapi caching menangkap beberapa di antaranya.) Sebaliknya versi cepat tahu itu harus membaca semuanya dan mengalirkan data sekitar 70 MB / detik. Itu bisa melewati meja 11 GB dalam waktu kurang dari 3 menit.