Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Tingkatkan kinerja kueri SQL Server di tabel besar

Jawaban Sederhana:TIDAK. Anda tidak dapat membantu kueri ad hoc pada tabel 238 kolom dengan Faktor Isi 50% pada Indeks Terkelompok.

Jawaban Lengkap:

Seperti yang telah saya nyatakan dalam jawaban lain tentang topik ini, desain Indeks adalah Seni dan Sains dan ada begitu banyak faktor yang perlu dipertimbangkan sehingga hanya ada sedikit, jika ada, aturan yang keras dan cepat. Anda perlu mempertimbangkan:volume operasi DML vs SELECT, subsistem disk, indeks/pemicu lain di atas tabel, distribusi data di dalam tabel, adalah kueri yang menggunakan kondisi SARGable WHERE, dan beberapa hal lain yang bahkan tidak dapat saya ingat dengan benar sekarang.

Saya dapat mengatakan bahwa tidak ada bantuan yang dapat diberikan untuk pertanyaan tentang topik ini tanpa pemahaman tentang Tabel itu sendiri, indeksnya, pemicunya, dll. Sekarang Anda telah memposting definisi tabel (masih menunggu Indeks tetapi definisi Tabel saja menunjuk ke 99% dari masalah) Saya dapat menawarkan beberapa saran.

Pertama, jika definisi tabel akurat (238 kolom, 50% Fill Factor) maka Anda dapat mengabaikan sisa jawaban / saran di sini;-). Maaf untuk menjadi kurang politis di sini, tapi serius, ini adalah pengejaran angsa liar tanpa mengetahui secara spesifik. Dan sekarang setelah kita melihat definisi tabel, menjadi sedikit lebih jelas mengapa kueri sederhana membutuhkan waktu begitu lama, bahkan saat kueri pengujian (Pembaruan #1) berjalan begitu cepat.

Masalah utama di sini (dan dalam banyak situasi kinerja buruk) adalah pemodelan data yang buruk. 238 kolom tidak dilarang sama seperti memiliki 999 indeks tidak dilarang, tetapi juga umumnya tidak terlalu bijaksana.

Rekomendasi:

  1. Pertama, tabel ini benar-benar perlu dirombak. Jika ini adalah tabel gudang data maka mungkin, tetapi jika tidak maka bidang ini benar-benar perlu dipecah menjadi beberapa tabel yang semuanya dapat memiliki PK yang sama. Anda akan memiliki tabel catatan master dan tabel anak hanya bergantung pada info berdasarkan atribut yang umumnya terkait dan PK tabel tersebut sama dengan PK tabel master dan karenanya juga FK ke tabel master. Akan ada hubungan 1-1 antara master dan semua tabel anak.
  2. Penggunaan ANSI_PADDING OFF mengganggu, belum lagi tidak konsisten dalam tabel karena berbagai penambahan kolom dari waktu ke waktu. Tidak yakin apakah Anda dapat memperbaikinya sekarang, tetapi idealnya Anda akan selalu ANSI_PADDING ON , atau setidaknya memiliki pengaturan yang sama di semua ALTER TABLE pernyataan.
  3. Pertimbangkan untuk membuat 2 Grup File tambahan:Tabel dan Indeks. Sebaiknya jangan menaruh barang Anda di PRIMARY karena di situlah SQL SERVER menyimpan semua data dan meta-data tentang objek Anda. Anda membuat Tabel dan Indeks Clustered Anda (karena itu adalah data untuk tabel) di [Tables] dan semua indeks Non-Clustered di [Indexes]
  4. Tingkatkan Fill Factor dari 50%. Angka yang rendah ini kemungkinan mengapa ruang indeks Anda lebih besar dari ruang data Anda. Melakukan Pembuatan Ulang Indeks akan membuat ulang halaman data dengan maksimal 4k (dari total ukuran halaman 8k) yang digunakan untuk data Anda sehingga tabel Anda tersebar di area yang luas.
  5. Jika sebagian besar atau semua kueri memiliki "ER101_ORG_CODE" di WHERE kondisi, kemudian pertimbangkan untuk memindahkannya ke kolom utama dari indeks berkerumun. Dengan asumsi bahwa itu digunakan lebih sering daripada "ER101_ORD_NBR". Jika "ER101_ORD_NBR" digunakan lebih sering maka simpanlah. Tampaknya, dengan asumsi bahwa nama bidang berarti "OrganizationCode" dan "OrderNumber", bahwa "OrgCode" adalah pengelompokan yang lebih baik yang mungkin memiliki beberapa "OrderNumber" di dalamnya.
  6. Poin kecil, tetapi jika "ER101_ORG_CODE" selalu 2 karakter, gunakan CHAR(2) bukannya VARCHAR(2) karena akan menyimpan satu byte di header baris yang melacak ukuran lebar variabel dan menambahkan lebih dari jutaan baris.
  7. Seperti yang telah disebutkan orang lain di sini, menggunakan SELECT * akan mengganggu kinerja. Tidak hanya karena membutuhkan SQL Server untuk mengembalikan semua kolom dan karenanya lebih mungkin untuk melakukan Pemindaian Indeks Clustered terlepas dari indeks Anda yang lain, tetapi SQL Server juga membutuhkan waktu untuk pergi ke definisi tabel dan menerjemahkan * ke semua nama kolom. Seharusnya sedikit lebih cepat untuk menentukan semua 238 nama kolom di SELECT daftar meskipun itu tidak akan membantu masalah Pindai. Tapi apakah Anda benar-benar membutuhkan 238 kolom sekaligus?

Semoga berhasil!

PERBARUI
Demi kelengkapan pertanyaan "bagaimana meningkatkan kinerja pada tabel besar untuk kueri ad-hoc", perlu dicatat bahwa sementara itu tidak akan membantu untuk kasus khusus ini, JIKA seseorang menggunakan SQL Server 2012 (atau lebih baru ketika saatnya tiba) dan JIKA tabel tidak diperbarui, maka menggunakan Indeks Columnstore adalah sebuah pilihan. Untuk detail selengkapnya tentang fitur baru tersebut, lihat di sini:http://msdn.microsoft.com/en-us/library/gg492088.aspx (Saya yakin ini dibuat agar dapat diperbarui mulai dari SQL Server 2014).

PERBARUI 2
Pertimbangan tambahan adalah:

  • Aktifkan kompresi pada Indeks Tergugus. Opsi ini tersedia di SQL Server 2008, tetapi sebagai fitur khusus Edisi Perusahaan. Namun, pada SQL Server 2016 SP1 , Kompresi Data tersedia di semua edisi! Silakan lihat halaman MSDN untuk Kompresi Data untuk detail tentang Kompresi Baris dan Halaman.
  • Jika Anda tidak dapat menggunakan Kompresi Data, atau jika tidak memberikan banyak manfaat untuk tabel tertentu, maka JIKA Anda memiliki kolom dengan tipe panjang tetap (INT , BIGINT , TINYINT , SMALLINT , CHAR , NCHAR , BINARY , DATETIME , SMALLDATETIME , MONEY , dll) dan lebih dari 50% baris adalah NULL , lalu pertimbangkan untuk mengaktifkan SPARSE opsi yang tersedia di SQL Server 2008. Silakan lihat halaman MSDN untuk Gunakan Kolom Jarang untuk detailnya.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Perilaku Rencana Kueri Tabel Temporal SQL Server 2016

  2. Hapus Acara dari Database Mail Log di SQL Server (T-SQL)

  3. Siapkan VM baru untuk SQL Server 2014 CTP1

  4. Cara Mengganti Nama Nama Tabel di SQL Server

  5. Bagaimana cara memasukkan tabel data ke tabel database SQL Server?