it-swarm.asia

Aturan keras dan cepat untuk menyertakan kolom dalam indeks

Apakah ada aturan yang keras dan cepat untuk memutuskan kolom apa dan urutan apa yang harus dimasukkan dalam indeks Non-clustered. Saya baru saja membaca posting ini https://stackoverflow.com/questions/1307990/why-use-the-include-clause-when-creating-an-index dan saya menemukan itu untuk kueri berikut :

SELECT EmployeeID, DepartmentID, LastName
FROM Employee
WHERE DepartmentID = 5

Poster menyarankan untuk membuat indeks seperti ini:

CREATE NONCLUSTERED INDEX NC_EmpDep 
  ON Employee(EmployeeID, DepartmentID)
  INCLUDE (Lastname)

inilah pertanyaan saya mengapa kita tidak dapat membuat indeks seperti ini

CREATE NONCLUSTERED INDEX NC_EmpDep 
      ON Employee( EmployeeID, DepartmentID, LastName)

atau

    CREATE NONCLUSTERED INDEX NC_EmpDep 
          ON Employee( EmployeeID, LastName)
INCLUDE (DepartmentID)

dan apa yang membuat poster memutuskan untuk memasukkan kolom LastName. Kenapa tidak kolom lain? dan bagaimana memutuskan dalam urutan apa kita harus menyimpan kolom di sana?

38
Rocky Singh

Saran indeks oleh marc_s salah. Saya telah menambahkan komentar. (Dan jawaban saya juga diterima!)

Indeks untuk kueri ini adalah

CREATE NONCLUSTERED INDEX NC_EmpDep 
  ON Employee(DepartmentID)
  INCLUDE (Lastname, EmployeeID)

Indeks biasanya

CREATE INDEX <name> ON <table> (KeyColList) INCLUDE (NonKeyColList)

Dimana:

  • KeyColList = Kolom kunci = digunakan untuk pembatasan dan pemrosesan baris
    DIMANA, BERGABUNG, MEMESAN OLEH, GRUP OLEH dll
  • NonKeyColList = Kolom non-kunci = digunakan dalam SELECT dan agregasi (mis. SUM (col)) setelah pemilihan/pembatasan
48
gbn

JNK dan gbn telah memberikan jawaban yang bagus, tetapi juga layak mempertimbangkan gambaran besarnya - tidak hanya berfokus pada satu permintaan. Meskipun kueri khusus ini mungkin mendapat manfaat dari indeks (# 1):

Employee(DepartmentID) INCLUDE (Lastname, EmployeeID)

Indeks ini tidak membantu sama sekali jika permintaan sedikit berubah, seperti:

SELECT EmployeeID, DepartmentID, LastName
FROM Employee
WHERE DepartmentID = 5 AND LastName = 'Smith'

Ini membutuhkan indeks (# 2):

Employee(DepartmentID, LastName) INCLUDE (EmployeeID)

Bayangkan Anda memiliki 1.000 karyawan di Departemen 5. Dengan menggunakan indeks # 1, untuk menemukan semua Smiths, Anda harus mencari semua 1.000 baris di Departemen 5, karena kolom yang disertakan bukan bagian dari kunci. Dengan menggunakan indeks # 2, Anda dapat mencari langsung ke Departemen 5, LastName Smith.

Dengan demikian, Indeks # 2 lebih bermanfaat untuk melayani berbagai pertanyaan yang lebih luas - tetapi biayanya adalah kunci indeks yang lebih membengkak, yang akan membuat halaman indeks yang tidak berdaun lebih besar. Setiap sistem akan berbeda, jadi tidak ada aturan umum di sini.


Sebagai catatan, ada baiknya menunjukkan bahwa jika EmployeeID adalah kunci pengelompokan untuk tabel ini - dengan asumsi indeks berkerumun - maka Anda tidak perlu memasukkan EmployeeID - itu ada di semua indeks non-cluster, artinya indeks # 2 bisa saja menjadi

Employee(DepartmentID, LastName)
19
Jim McLeod

Saya tidak yakin bagaimana Anda mendapatkan yang pertama. Bagi saya, untuk permintaan itu, saya akan menggunakan:

CREATE NONCLUSTERED INDEX NC_EmpDep 
  ON Employee(DepartmentID)
  INCLUDE (EmployeeID, Lastname)

Tidak ada "Aturan keras dan cepat" untuk hampir semua hal dalam SQL.

Tetapi, untuk contoh Anda, satu-satunya bidang yang akan digunakan indeks adalah DepartmentID karena berada dalam klausa WHERE.

Kolom lain hanya perlu mudah diakses dari sana. Anda memilih berdasarkan DepartmentID maka INCLUDE memiliki bidang-bidang tersebut di simpul daun indeks.

Anda tidak ingin menggunakan contoh Anda yang lain karena mereka tidak akan berfungsi untuk indeks ini.

Pikirkan indeks seperti buku telepon. Sebagian besar buku telepon dipesan berdasarkan Nama Belakang, Nama Depan, dan Inisial Tengah. Jika Anda tahu nama depan seseorang, tetapi bukan nama belakangnya, buku telepon itu tidak berguna karena Anda tidak dapat mencari nama depan berdasarkan urutan indeks buku telepon itu.

Kolom INCLUDE seperti nomor telepon, alamat, dll. Informasi lainnya untuk setiap entri dalam buku.

EDIT:

Untuk lebih memperjelas mengapa tidak menggunakan:

CREATE NONCLUSTERED INDEX NC_EmpDep 
          ON Employee( EmployeeID, LastName)
INCLUDE (DepartmentID)

Indeks ini hanya berguna jika Anda memiliki EmployeeID atau KEDUANYA EmployeeID dan LastName dalam klausa WHERE Anda. Ini cukup banyak KEBALIKAN dari apa yang Anda butuhkan untuk permintaan ini.

7
JNK

Saya pikir Anda mungkin masih dapat menggunakan indeks (employee_id, department_id), tetapi Anda harus memasukkan baris 'dummy' di frasa mana, seperti: "employee_id = employee_id)

  • memiliki indeks pada (employee_id, departemnent_id),
  • harus mencari/membatasi hanya pada department_id
  • mengetahui itu tidak akan menggunakan indeks karena urutan yang salah (atau hal-hal telah berubah sekarang, dan "trik" berikut tidak lagi diperlukan. Saya seorang "oldy"?) .
  • Gunakan trik "lama"?

    pilih * dari Emp karyawan
    di mana emp.employee_id = emp.employee_id
    dan emp.department_id = 5

(Jadi saya tidak fokus pada bagian sertakan di sini dari Lastname, tetapi pada kunci ya/atau tidak digunakan.)

Salam,

Miguell

0
Miguel Leeuwe