Pertanyaan ini adalah tentang kinerja indeks SQL Server dengan varchar(2000)
sebagai INCLUDE
dalam indeks yang meliputi.
Saya mencoba untuk meningkatkan kinerja dalam aplikasi database yang lambat dan tidak stabil. Dalam beberapa kasus, data yang diakses melalui string varchar besar, dengan query termasuk operasi string multple seperti SUBSTRING()
, SPACE()
, dan DATALENGTH()
. Berikut ini contoh akses yang disederhanakan;
update fattable set col3 =
SUBSTRING(col3,1,10) + '*' +
SUBSTRING(col3,12,DATALENGTH(col3)-12)
from fattable where substring(col3,10,1) = 'A' and col2 = 2
Skema terlihat seperti ini:
CREATE TABLE [dbo].[FatTable](
[id] [bigint] IDENTITY(1,1) NOT NULL,
[col1] [nchar](12) NOT NULL,
[col2] [int] NOT NULL,
[col3] [varchar](2000) NOT NULL, ...
Indeks berikut telah ditentukan, dengan bidang penutup pada kolom teks besar.
CREATE NONCLUSTERED INDEX [IndexCol2Col3] ON [dbo].[FatTable] ( [col2] ASC )
INCLUDE( [col3] )
Dari apa yang saya baca itu BAD untuk meletakkan bidang data besar dalam indeks. Saya telah membaca beberapa artikel, termasuk http://msdn.microsoft.com/en-us/library/ms190806.aspx yang membahas dampak ukuran halaman dan disk pada kinerja indeks. Ini dikatakan, rencana permintaan pasti menggunakan indeks penutup. Saya tidak memiliki informasi yang cukup untuk menentukan berapa sebenarnya biaya saya dalam hal beban sistem. Saya tahu bahwa secara keseluruhan, sistem berkinerja buruk, dan saya khawatir ini adalah salah satu masalah. Pertanyaan:
Apakah menempatkan
varchar(2000)
kolom ini dalam indeksINCLUDE
merupakan ide yang bagus?Karena
INCLUDE
bidang disimpan dalam node daun, apakah mereka memiliki banyak dampak kinerja indeks?
Pembaruan: Terima kasih atas balasan yang sangat baik! Ini adalah pertanyaan yang tidak adil dalam beberapa hal - seperti yang Anda katakan, tidak ada jawaban benar mutlak tanpa statistik dan profil yang sebenarnya. Seperti banyak masalah kinerja, saya kira jawabannya adalah "itu tergantung".
sumber
VARCHAR(2000)
yang biasanya menyimpan hanya sepuluh karakter adalah satu hal; 2.000 byte per rekaman yang solid adalah sesuatu yang lain.Jawaban:
Pernah merupakan kata yang besar, tetapi, secara umum, tidak, saya tidak akan menempatkan bidang varchar (2000) ke dalam TERMASUK.
Dan ya, cara data disimpan di tingkat halaman dapat berdampak serius pada kinerja indeks, tergantung pada bagaimana indeks digunakan.
Masalahnya adalah, semakin banyak baris data yang dapat Anda masukkan ke dalam sebuah halaman, semakin sedikit halaman yang harus diakses, semakin cepat sistem Anda, untuk sebagian besar. Menambahkan kolom yang sangat besar berarti lebih sedikit informasi yang disimpan pada sebuah halaman, jadi, jika rentang pencarian atau pemindaian, lebih banyak halaman harus dibaca untuk mengambil kembali data, dengan serius memperlambat hal-hal.
Untuk mengetahui dengan pasti apakah ini merupakan masalah pada kueri Anda, atau pada sistem Anda, Anda harus memantau bacaan, terutama jumlah halaman yang digunakan kueri.
sumber
Bisakah Anda meninjau kunci indeks yang dikelompokkan saat ini, dan mungkin membuat
col2
kunci indeks yang dikelompokkan sebagai gantinya? Dengan cara ini Anda mendapatkan perilaku 'sertakan' penutup (karena indeks berkerumun selalu 'termasuk' semuanya) tanpa menduplikasi data. Ini, tentu saja, tunduk pada banyakif
danbut
, meskipun demikian mungkin layak dipertimbangkan. Tentu saja jika indeks cluster saat ini menegakkan batasan (kunci primer, unik) kata kendala harus dipindahkan ke indeks non-clustered.sumber
Sulit dijawab. Itu semua akan tergantung pada rasio baca: tulis Anda. Sudahkah Anda menguji beban kerja atau mensimulasikan seluruh siklus bisnis pada sistem pengujian, dengan dan tanpa kolom yang disertakan? Pencarian tanpa biaya mungkin banyak, tetapi jika Anda memperbarui data lebih sering daripada membacanya, itu mungkin ok.
sumber
VARCHAR(2000)
kolom ini , atau apakah Anda memecahkan masalah kinerja kueri yang sangat spesifik yang tidak mewakili sebagian besar kueri? Seperti yang disarankan Grant jika kolom ini tidak digunakan dalam banyak pertanyaan, atau benar-benar menyebabkan masalah untuk pencarian, mungkin akan lebih baik untuk membayar harga untuk pencarian ketika Anda membutuhkannya, tetapi tidak membayar penyimpanan ketika Anda tidak . Sekali lagi, sangat sulit untuk mengatakan di sisi mana Anda seharusnya berada, karena kami tidak benar-benar memiliki spesifikasi (dan bahkan lebih sulit karena Anda tidak dapat menguji - Anda harus berusaha untuk memperbaikinya).Saya tahu saya terlambat untuk pesta ini, tetapi saya akan mengindeks persis ekspresi yang digunakan untuk mencari baris, seperti substring (col3,10,1). Jika seluruh col3 digunakan, saya akan mengindeks CHECKSUM (col3) (memahami bahwa mungkin saja ada tabrakan).
sumber