Saya membuat tabel big_table sesuai dengan skema Anda
create table big_table
(
updatetime datetime not null,
name char(14) not null,
TheData float,
primary key(Name,updatetime)
)
Saya kemudian mengisi tabel dengan 50.000 baris dengan kode ini:
DECLARE @ROWNUM as bigint = 1
WHILE(1=1)
BEGIN
set @rownum = @ROWNUM + 1
insert into big_table values(getdate(),'name' + cast(@rownum as CHAR), cast(@rownum as float))
if @ROWNUM > 50000
BREAK;
END
Menggunakan SSMS, saya kemudian menguji kedua kueri dan menyadari bahwa dalam kueri pertama Anda mencari MAX TheData dan di kedua, MAX dari updatetime
Saya memodifikasi permintaan pertama untuk mendapatkan MAX dari updatetime
set statistics time on -- execution time
set statistics io on -- io stats (how many pages read, temp tables)
-- query 1
SELECT MAX([UpdateTime])
FROM big_table
-- query 2
SELECT MAX([UpdateTime]) AS value
from
(
SELECT [UpdateTime]
FROM big_table
group by [UpdateTime]
) as t
set statistics time off
set statistics io off
Menggunakan Waktu Statistik, saya mendapatkan kembali jumlah milidetik yang diperlukan untuk mem-parsing, mengkompilasi, dan mengeksekusi setiap pernyataan
Menggunakan Statistik IO saya mendapatkan kembali informasi tentang aktivitas disk
WAKTU STATISTIK dan STATISTIK IO memberikan informasi yang berguna. Seperti tabel sementara yang digunakan (ditunjukkan oleh meja kerja). Juga berapa banyak halaman logis yang dibaca dibaca yang menunjukkan jumlah halaman database yang dibaca dari cache.
Saya kemudian mengaktifkan paket Eksekusi dengan CTRL + M (aktif menunjukkan rencana eksekusi aktual) dan kemudian mengeksekusi dengan F5.
Ini akan memberikan perbandingan kedua pertanyaan.
Ini adalah output dari Tab Pesan
- Pertanyaan 1
Tabel 'big_table'. Pindai hitungan 1, bacaan logis 543 , bacaan fisik 0, bacaan baca depan 0, bacaan logis lob 0, bacaan fisik lob 0, bacaan baca lob depan 0.
Waktu Eksekusi SQL Server:
Waktu CPU = 16 ms, waktu yang berlalu = 6 ms .
- Pertanyaan 2
Tabel 'Meja Kerja '. Pindai jumlah 0, bacaan logis 0, bacaan fisik 0, bacaan baca-depan 0, bacaan logis lob 0, bacaan fisik lob 0, bac baca baca-depan 0.
Tabel 'big_table'. Pindai hitungan 1, bacaan logis 543 , bacaan fisik 0, bacaan baca depan 0, bacaan logis lob 0, bacaan fisik lob 0, bacaan baca lob depan 0.
Waktu Eksekusi SQL Server:
Waktu CPU = 0 ms, waktu yang berlalu = 35 ms .
Kedua kueri menghasilkan 543 bacaan logis, tetapi kueri kedua memiliki waktu yang telah berlalu 35ms sedangkan yang pertama hanya memiliki 6ms. Anda juga akan melihat bahwa hasil kueri kedua dalam penggunaan tabel sementara di tempdb, ditunjukkan oleh kata meja kerja . Meskipun semua nilai untuk tabel kerja adalah 0, pekerjaan masih dilakukan di tempdb.
Lalu ada output dari tab rencana Eksekusi yang sebenarnya di sebelah tab Pesan
Menurut rencana eksekusi yang disediakan oleh MSSQL, permintaan kedua yang Anda berikan memiliki total biaya batch 64% sedangkan yang pertama hanya biaya 36% dari total batch, sehingga permintaan pertama membutuhkan lebih sedikit pekerjaan.
Menggunakan SSMS, Anda dapat menguji dan membandingkan kueri Anda dan mencari tahu bagaimana MSSQL mem-parsing kueri Anda dan objek apa: tabel, indeks, dan / atau statistik jika ada yang digunakan untuk memenuhi kueri tersebut.
Satu catatan tambahan yang perlu diingat ketika pengujian adalah membersihkan cache sebelum pengujian, jika memungkinkan. Ini membantu untuk memastikan bahwa perbandingan akurat dan ini penting ketika memikirkan aktivitas disk. Saya mulai dengan DBCC DROPCLEANBUFFERS dan DBCC FREEPROCCACHE untuk menghapus semua cache. Berhati-hatilah meskipun tidak menggunakan perintah ini pada server produksi yang benar-benar digunakan karena Anda akan secara efektif memaksa server untuk membaca semuanya dari disk ke dalam memori.
Ini dokumentasi yang relevan.
- Bersihkan cache rencana dengan DBCC FREEPROCCACHE
- Hapus semuanya dari kumpulan buffer dengan DBCC DROPCLEANBUFFERS
Menggunakan perintah ini mungkin tidak dimungkinkan tergantung pada bagaimana lingkungan Anda digunakan.
Diperbarui 10/28 12:46
Membuat koreksi pada gambar rencana eksekusi dan output statistik.
getdate()
keluar dari loop