Jika suatu basis data hanya memiliki satu sisipan, apakah buruk untuk mengindeks setiap kombinasi kolom yang memungkinkan?

23

Saya bekerja pada sistem pelaporan yang akan membutuhkan kueri pemilihan besar, tetapi didasarkan pada database yang hanya diisi sekali. Sistem manajemen basis data adalah Microsoft SQL Server 2017. Mungkin ada cara yang lebih baik untuk merancang sistem seperti ini, tetapi mari kita pendekatan ini secara teoritis.

Secara teoritis:

  1. Jika kita memiliki database yang sangat besar (150M + baris pada beberapa tabel)
  2. Dan kita dapat mengasumsikan bahwa basis data hanya akan diisi satu kali.

Bisakah pengindeksan setiap kombinasi kolom yang mungkin memiliki dampak kinerja negatif pada kueri pemilihan?

Miring
sumber
4
Setiap kemungkinan kombinasi hampir tidak praktis. Pendekatan yang lebih masuk akal adalah dengan mengindeks secara manual tetapi sangat murah hati. Itu pasti bisa masuk akal.
usr
12
Saya sarankan menulis ulang judul atau teks tebal Anda agar konsisten. Sekilas saya bingung dengan jawaban terpilih tertinggi "Ya"
aaaaaa
150M baris besar untuk satu tabel, tetapi tidak besar untuk database. Secara praktis, sistem pelaporan hanya menggunakan subset kecil dari kombinasi kolom yang mungkin, yang terbaik adalah fokus pada kombinasi kunci setidaknya pada awalnya, dan kemudian menjadi lebih kompleks hanya jika diperlukan.
pojo-guy

Jawaban:

36

Ya, itu akan memengaruhi waktu kompilasi rencana awal karena pengoptimal akan memiliki banyak jalur akses tambahan untuk dipertimbangkan.

Karena Anda menggunakan SQL Server 2017, memuat sekali, dan menjalankan laporan, mengapa tidak menggunakan indeks toko kolom berkerumun saja?

Itu tampaknya menjadi solusi ideal untuk kebutuhan Anda untuk mengindeks setiap kombinasi kolom yang mungkin.

Indeks Columnstore - Ikhtisar

Erik Darling
sumber
Columnstore adalah tempat saya akan pergi juga, tetapi saya hanya ingin tahu ... bukankah optimizer bekerja berlawanan dengan apa yang Anda gambarkan? Maksud saya alih-alih memindai indeks yang tersedia dan "bertanya-tanya" yang mana dari mereka yang bisa berguna bukan egzamin permintaan dan "pikirkan" indeks sempurna untuk permintaan itu, lalu memeriksa apakah ada? (Jika tidak maka pesan indeks yang hilang dihasilkan.) Jika saya benar (saya tidak tahu, hanya menebak-nebak), maka bahkan jika ada ribuan indeks, seharusnya waktu yang terasa lebih lama daripada hanya memiliki beberapa dari mereka.
Limonka
26

Jika Anda memiliki N kolom dalam sebuah tabel, setiap kombinasi kolom yang memungkinkan adalah 2 ^ N-1 (menghapus set kosong). Untuk 10 kolom yang berarti 1023 indeks, untuk 20 kolom kita berakhir dengan indeks 1048575 kekalahan. Sebagian besar indeks tidak akan pernah digunakan tetapi harus dipertimbangkan oleh pengoptimal. Mungkin saja pengoptimal akan memilih indeks sub-optimal daripada yang lebih baik. Saya tidak akan mengambil jalan untuk menghasilkan semua jenis indeks, alih-alih mencoba mencari tahu indeks apa yang benar-benar bermanfaat.

EDIT mengoreksi jumlah indeks yang mungkin

Seperti yang ditunjukkan Jeff , ini bahkan lebih buruk daripada 2 ^ N (power-set) karena (3,2,1) jelas berbeda dari (1,2,3). Untuk kolom N kita dapat memilih posisi pertama dalam indeks yang berisi semua kolom dengan cara N. Untuk posisi kedua dengan cara N-1, dll. Karena itu, kita berakhir dengan N! indeks berbeda ukuran penuh. Tak satu pun dari indeks ini dimasukkan oleh indeks lain di set ini. Selain itu, kami tidak dapat menambahkan indeks lain yang lebih pendek sehingga tidak tercakup oleh indeks lengkap apa pun. Oleh karena itu, jumlah indeks adalah N !. Contoh untuk 10 kolom, menjadi 10! = 3628800 indeks dan untuk 20 (drumroll) 2432902008176640000 indeks. Ini adalah angka yang sangat besar, jika kita meletakkan sebuah titik untuk setiap indeks satu mm bagian, itu akan membutuhkan cahaya 94 hari untuk melewati semua titik. Semua dan semua, jangan ;-)

Lennart
sumber
6
Lebih buruk lagi: urutan kolom dalam indeks bisa menjadi penting. Karena itu, Anda mendapatkan maksimum N! indeks.
Jeff
2
Tetapi Anda tidak perlu indeks yang merupakan awalan dari indeks lain.
Barmar
3
Ini bahkan lebih buruk. Ada kombinasi ASC dan DESC untuk setiap indeks.
ypercubeᵀᴹ
2
Dan jauh lebih buruk, ada indeks TERMASUK.
ypercubeᵀᴹ
2
Dan sejumlah besar indeks parsial.
ypercubeᵀᴹ
7

Tidak.

Tidak praktis untuk mengindeks "segalanya", tetapi Anda dapat mengindeks "sebagian besar" darinya.

Ini masalahnya. Jika tabel memiliki Nkolom, maka jumlah indeks yang mungkin adalah N!. Katakanlah sebuah tabel memiliki 10 kolom, maka Anda tidak hanya memiliki 10kemungkinan indeks, tetapi 10!. Itu adalah ... 3.628.800 ... di satu meja. Itu banyak ruang disk, I / O disk, cache, dan mencari waktu.

Mengapa? Beberapa alasan:

  • Indeks Lightwwight biasanya di-cache, sesuatu yang membuat mereka cepat menyala. Jika Anda memiliki 3 juta dari mereka, mereka TIDAK akan di-cache.

  • Pengoptimal SQL mungkin membutuhkan banyak waktu untuk memutuskan mana yang lebih baik untuk digunakan, khususnya saat menggunakan gabungan.

  • Pengoptimal SQL dapat menyerah menggunakan algoritma yang komprehensif, dan mencoba algoritma heuristik sebagai gantinya. Ini mungkin "kurang optimal". PostgreSQL, misalnya, memiliki opsi berbeda untuk "kueri tabel kurang dari 8", dan "kueri tabel lebih dari 8".

  • Indeks seharusnya lebih ringan dari heap. Jika Anda mengindeks semuanya, maka indeks menjadi seberat tumpukan ... sesuatu yang mengalahkan tujuan indeks.

Impaler
sumber
Bukankah angka 2 ^ 10? Setiap kolom dimasukkan atau dikecualikan dari indeks yang diberikan. Apakah pesanan itu penting?
RemcoGerlich
2
@RemcoGerlich ya, pesanan penting.
ypercubeᵀᴹ
2

Tidak, itu mungkin tidak akan berdampak negatif pada SELECTkueri, tetapi

  • Ini akan menyebabkan penggunaan disk yang tinggi.
  • Ini akan sangat meningkatkan INSERTbiaya.
  • Sebagian besar indeks Anda tidak akan pernah digunakan.
  • Banyak WHEREekspresi kondisi masih tidak akan menggunakan indeks, terutama yang lebih kompleks.
  • Hitungan indeks yang diperlukan akan meningkat secara eksponensial dengan jumlah kolom. Yaitu jika Anda memiliki, misalnya, 8 kolom, Anda perlu 256 indeks untuk semua kemungkinan kombinasi.
peterh mengatakan mengembalikan Monica
sumber
Itu benar-benar dapat menyebabkan masalah untuk waktu kompilasi.
Erik Darling
@sp_BlitzErik Apakah Anda berpikir tentang ORM di aplikasi?
peterh mengatakan mengembalikan Monica
Tidak, lihat jawaban saya.
Erik Darling
@sp_BlitzErik Wow, senang melihat!
peterh mengatakan mengembalikan Monica