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

Memahami Pentingnya Pengaturan Memori di SQL Server

Memori adalah salah satu di antara sumber daya yang membentuk segitiga kinerja—CPU dan penyimpanan menjadi dua lainnya. Jika satu terkena, dua lainnya mengambil beban untuk mencoba membawa kinerja ke tingkat yang dapat diterima, tetapi selalu ada trade-off. Transaksi apa pun yang tidak dapat dilakukan ke memori, transaksi tersebut akan diteruskan ke subsistem disk oleh SQL Server. Hal ini menyebabkan kemacetan kinerja. Oleh karena itu, statistik tunggu dapat membantu mengidentifikasi masalah kinerja pada SQL Server.

Dalam artikel ini, topik berikut dibahas:

  1. Memahami internal pengaturan dan konfigurasi memori SQL Server
  2. Memori SQL Server dan dampaknya pada database dan kinerja aplikasi
  3. Membahas berbagai komponen SQL Server yang berkontribusi pada penggunaan memori
  4. Praktik terbaik dan rekomendasi untuk ukuran memori
  5. Laporan memori multi-server
  6. Dan banyak lagi…

Internal manajemen memori

SQL Server memiliki Unit Manajemen Memori yang melakukan manajemen memori dinamis otomatis berdasarkan beban kerja sistem. Memori ini adalah ruang volatil yang sangat penting bagi Bisnis – Kebutuhan teknologi saat ini, dengan ukuran yang tepat sangat penting untuk kinerja aplikasi yang optimal.

Namun, kita semua tahu bahwa saat menyiapkan server, ukurannya berisi beberapa nilai default. dalam beberapa kasus, kami segera mengetahui bahwa SQL Server menggunakan hampir semua memori di server, meskipun tidak ada aktivitas yang terlihat di database, menimbulkan pertanyaan:Apakah nilai default salah? Jika ya, berapa ukuran yang tepat?

Manajemen Memori pada SQL Server bekerja pada algoritma Fill-and-Flush. Nilai default tidak membatasi konsumsi memori agar tidak bertambah kecuali ada permintaan dari Sistem Operasi.

Ukurannya tergantung pada berbagai komponen sistem—dalam banyak kasus, menyetelnya antara 70% dan 80% adalah titik awal yang baik. Kemudian, Anda juga harus memantaunya untuk melihat apa lagi yang mungkin Anda lewatkan dan apakah Anda harus mengubah pengaturannya. Jika Anda memiliki layanan lain di SQL Server (seharusnya Anda tidak melakukannya), Anda mungkin perlu meninggalkan lebih banyak, terutama jika layanan ini adalah babi memori. Pertimbangkan untuk meninjau kembali pengaturan memori instance SQL dalam salah satu skenario berikut:

  • Sistem Operasi tidak responsif
  • Kelelahan aplikasi
  • Operasi pencadangan yang memerlukan buffer memori besar
  • Objek yang Dioptimalkan dalam Memori
  • Indeks penyimpanan kolom, karena memerlukan volume memori yang besar untuk melakukan pemeliharaan indeks.

Pengaturan memori pada SQL Server cukup mudah. Anda dapat mengubah nilainya menggunakan sp_configure atau SSMS GUI. Ini adalah opsi online tetapi ingat bahwa menyetel atau menyetel ulang nilai ini dapat menyebabkan beberapa objek cache internal mengacak ulang, yang akan membuat sistem berjalan sedikit lebih lambat.

sp_configure 'memori server maks (MB)',

Dalam hal ini, angka “2147483647” berarti SQL Server tidak memiliki batas atas dan akan menggunakan semua memori di server.

Memori server minimum:memori server minimum sebagai nilai minimum; SQL Server akan mengkomit memori untuk digunakan sendiri hingga mencapai pengaturan memori server min. Setelah itu, ini akan mempertahankan setidaknya jumlah memori yang dapat digunakan ini.

Memori server maksimum:Dengan cara yang sama bahwa memori server minimum menyediakan lantai, memori server maksimum menyediakan batas.

Level memori min dan maks adalah batas bawah dan atas dari jumlah memori yang diizinkan untuk digunakan oleh kumpulan buffer. Kumpulan buffer adalah bagian terbesar dari memori yang dikonsumsi oleh SQL Server. Berikut ini adalah komponen SQL Server dalam instance SQL yang menggunakan memori dari buffer pool

  • Tembolok Laman Basis Data
  • Cache log internal
  • Cache prosedur atau cache paket kueri
  • Ruang Beban Kerja Kueri
  • Kunci (Pemberian memori)
  • Konteks koneksi
  • Mengoptimalkan kueri
  • Struktur data tingkat sistem

Nilai metrik penting seperti Mbytes yang Tersedia, Halaman/Detik, Rasio Hit Cache Buffer, PLE, dll. menentukan kinerja SQL Server.

Buffer Cache Hit Ratio khusus untuk setiap aplikasi. 90% biasanya dianggap diinginkan. Ini berarti bahwa lebih dari 90% permintaan dilayani oleh cache, yang merupakan hal yang baik. Jika nilainya lebih rendah, tambahkan lebih banyak memori hingga secara konsisten lebih tinggi dari 90%.

Bytes yang tersedia tidak lain adalah indikasi berapa banyak memori yang tersedia untuk digunakan. Penghitung Pages/sec menunjukkan berapa banyak halaman yang diambil dari disk, atau ditulis ke disk, keduanya karena kesalahan halaman keras.

PLE adalah singkatan dari Page Life Expectancy, yang merupakan indikasi berapa detik halaman akan tetap berada di kumpulan.

Misalnya,

$server = 'hqdbt01'

$counters = @("\Memory\Available MBytes",
 "\Memory\Pages/sec",
 "\SQLServer:Buffer Manager\Buffer cache hit ratio",
 "\SQLServer:Buffer Manager\Lazy writes/sec",
 "\SQLServer:Buffer Manager\Page life expectancy" 

 ) 
 $collections = Get-Counter -ComputerName $server -Counter $counters -SampleInterval 10 -MaxSamples 1
 Write-Output $collections 
 foreach ($collection in $collections) 
 {$sampling = $collection.CounterSamples | Select-Object -Property TimeStamp, Path, Cookedvalue 
  $sampling | Format-Table -AutoSize
   }

Rekomendasi dan praktik terbaik

Sekarang mari kita lihat secara singkat teknik untuk mengukur memori.

  1. Memori 1 GB dicadangkan untuk Sistem Operasi
  2. Masing-masing 1 GB untuk setiap 4 GB RAM setelah 4 GB awal, hingga 16 GB RAM
  3. Masing-masing 1 GB untuk setiap 8 GB di lebih dari 16 GB RAM

Misalnya, jika Anda memiliki Server Database RAM 32 GB, maka memori yang akan diberikan ke Sistem Operasi adalah

  1. 1 GB, alokasi minimum
  2. + 3 GB, karena 16 GB – 4 GB =12 GB; 12 GB dibagi 4 GB (setiap 4 GB mendapat 1 GB) adalah 3 GB.
  3. + 2 GB, sebagai 32 GB – 16 GB =16 GB; 16 dibagi 8 (masing-masing 8 GB setelah 16 GB mendapat 1 GB) adalah 2 GB

Jadi, secara total, untuk server dengan RAM 32 GB, 7 GB akan dicadangkan untuk Sistem Operasi. Ini adalah memori maksimum yang dialokasikan untuk SQL Server harus 25 GB. Demikian pula, untuk Server 64 GB, 10 GB harus dicadangkan untuk Sistem Operasi &54 GB harus dialokasikan untuk SQL Server.

Kita semua pernah mendengar atau menggunakan Windows Management Instrumentation (WMI). Ada beberapa kelas di WMI, yang memungkinkan kita untuk mengekstrak informasi tentang perangkat keras, perangkat lunak yang diinstal, sistem operasi, atau bahkan registri. Kami bahkan dapat mengubah setelan dan melakukan tindakan pada aspek ini.

Kelas win32_OperatingSystem adalah kelas WMI yang memiliki semua informasi yang diperlukan tentang aktif sistem operasi (jika Anda, katakanlah, dual boot). Kelas ini juga dapat digunakan untuk mendapatkan jumlah memori yang dialokasikan ke sistem operasi. Berikut adalah beberapa objek yang dapat dikembalikan oleh kelas, yang dapat membantu kami (memori diukur dalam kilobyte oleh kelas ini):

  • TotalVisibleMemorySize :Bidang ini menunjukkan total memori fisik yang dapat diakses oleh sistem operasi. Potongan memori yang tidak dapat diakses dapat menyebabkan nomor yang lebih kecil dari yang terpasang ditampilkan di sini.
  • FreePhysicalMemory :Ini memberi tahu kita berapa jumlah memori fisik yang tersisa.
  • TotalVirtualMemorySize :Ini adalah total memori virtual yang tersedia untuk digunakan oleh OS. Ini terdiri dari memori fisik yang terpasang di komputer, bersama dengan ukuran file halaman.
  • FreeVirtualMemory :Mirip dengan FreePhysicalMemory, tetapi menyertakan ruang kosong di memori paging juga.
$server='hqdbt01'
Get-WmiObject -Class Win32_OperatingSystem  -ComputerName $server | select  CSName,
@{name="TotalVirtualMemorySize";expression={($_.TotalVirtualMemorySize/1024).tostring("N0")}},
@{name="TotalVisibleMemorySize";expression={($_.TotalVisibleMemorySize/1024).tostring("N0")}},
@{name="FreePhysicalMemory";expression={($_.FreePhysicalMemory/1024).tostring("N0")}},
@{name="FreeVirtualMemory";expression={($_.FreeVirtualMemory/1024).tostring("N0")}},
@{name="FreeSpaceInPagingFiles";expression={($_.FreeSpaceInPagingFiles/1024).tostring("N0")}},
NumberofProcesses,
NumberOfUsers 

Kita dapat mengambil informasi file halaman menggunakan kelas WMI Win32_PageFileSetting.

$server='hqdbt01'
Get-WMIObject Win32_PageFileSetting -Computer $server|  select @{name="ServerName";expression={$_.__Server}}, Name, InitialSize, MaximumSize 

Kueri berikut memberikan detail penggunaan memori tingkat tinggi dari instance SQL.

SELECT 
	physical_memory_in_use_kb/1024 Physical_memory_in_use_MB, 
    large_page_allocations_kb/1024 Large_page_allocations_MB, 
    locked_page_allocations_kb/1024 Locked_page_allocations_MB,
    virtual_address_space_reserved_kb/1024 VAS_reserved_MB, 
    virtual_address_space_committed_kb/1024 VAS_committed_MB, 
    virtual_address_space_available_kb/1024 VAS_available_MB,
    page_fault_count Page_fault_count,
    memory_utilization_percentage Memory_utilization_percentage, 
    process_physical_memory_low Process_physical_memory_low, 
    process_virtual_memory_low Process_virtual_memory_low
FROM sys.dm_os_process_memory;

Siapkan skrip

Mari kita integrasikan ketiga keluaran di atas ke dalam satu keluaran memori:

  1. Struktur Memori Internal SQL menggunakan Penghitung
  2. Memori virtual dan fisik yang tersedia menggunakan objek WMI
  3. Pengaturan file halaman menggunakan WMI

Persiapan konten HTML adalah tentang mengisi nilai yang diumpankan dari bagian skrip yang berbeda, di antara tag yang tepat.

Script dapat membuat tag HTML yang valid. Berikut ini adalah fungsi-fungsi yang digunakan dalam skrip.

  1. writeHTMLHeader:fungsi ini digunakan untuk menghasilkan Header dan menentukan gaya untuk file HTML.
  2. writetableFooter:ini mendefinisikan tag HTML penutup.
  3. writeTableHeader:ini mendefinisikan judul keluaran tiga belas kolom untuk file HTML
  4. writeMemoryInfo:ini adalah fungsi yang melakukan penggabungan dua output kelas WMI. Output dari Win32_PageFileSetting, Win32_OperatingSystem dan SMO SQL dilewatkan sebagai argumen untuk fungsi ini. Nilai juga dapat diubah atau dimanipulasi lebih lanjut di bagian ini.
  5. Bagian email

[expand title="Kode"]

# First, let’s create a text file, where we will later save memory details


$MailServer='mail01.example.com'

$MemoryFileName = "f:\PowerSQL\Memory.htm"
New-Item -ItemType file $MemoryFileName -Force
# Function to write the HTML Header to the file
Function writeHtmlHeader
{
param($fileName)
$date = ( get-date ).ToString('yyyy/MM/dd')
Add-Content $fileName "<html>"
Add-Content $fileName "<head>"
Add-Content $fileName "<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>"
Add-Content $fileName '<title>SQLShack Memory Usage Report </title>'
add-content $fileName '<STYLE TYPE="text/css">'
add-content $fileName  "<!--"
add-content $fileName  "td {"
add-content $fileName  "font-family: Tahoma;"
add-content $fileName  "font-size: 11px;"
add-content $fileName  "border-top: 1px solid #999999;"
add-content $fileName  "border-right: 1px solid #999999;"
add-content $fileName  "border-bottom: 1px solid #999999;"
add-content $fileName  "border-left: 1px solid #999999;"
add-content $fileName  "padding-top: 0px;"
add-content $fileName  "padding-right: 0px;"
add-content $fileName  "padding-bottom: 0px;"
add-content $fileName  "padding-left: 0px;"
add-content $fileName  "}"
add-content $fileName  "body {"
add-content $fileName  "margin-left: 5px;"
add-content $fileName  "margin-top: 5px;"
add-content $fileName  "margin-right: 0px;"
add-content $fileName  "margin-bottom: 10px;"
add-content $fileName  ""
add-content $fileName  "table {"
add-content $fileName  "border: thin solid #000000;"
add-content $fileName  "}"
add-content $fileName  "-->"
add-content $fileName  "</style>"
Add-Content $fileName "</head>"
Add-Content $fileName "<body>"

add-content $fileName  "<table width='100%'>"
add-content $fileName  "<tr bgcolor='#CCCCCC'>"
add-content $fileName  "<td colspan='13' height='25' align='center'>"
add-content $fileName  "<font face='tahoma' color='#003399' size='4'><strong>SQLShack Memory Usage Report - $date</strong></font>"
add-content $fileName  "</td>"
add-content $fileName  "</tr>"
add-content $fileName  "</table>"

}

# Function to write the HTML Header to the file
Function writeTableHeader
{
param($fileName)

Add-Content $fileName "<tr bgcolor=#CCCCCC>"
Add-Content $fileName "<td width='10%' align='center'>ServerName</td>"
Add-Content $fileName "<td width='10%' align='center'>TotalVirtualMemorySize</td>"
Add-Content $fileName "<td width='10%' align='center'>TotalVisibleMemorySize</td>"
Add-Content $fileName "<td width='10%' align='center'>FreePhysicalMemory</td>"
Add-Content $fileName "<td width='10%' align='center'>FreeVirtualMemory</td>"
Add-Content $fileName "<td width='10%' align='center'>FreeSpaceInPagingFiles</td>"
Add-Content $fileName "<td width='10%' align='center'>NumberofProcesses</td>"
Add-Content $fileName "<td width='10%' align='center'>NumberOfUsers</td>"
Add-Content $fileName "<td width='10%' align='center'>PageFile</td>"
Add-Content $fileName "<td width='10%' align='center'>Page-InitialSize</td>"
Add-Content $fileName "<td width='10%' align='center'>Page-MaxSize</td>"
Add-Content $fileName "<td width='10%' align='center'>SQLMaxMemory</td>"
Add-Content $fileName "<td width='10%' align='center'>SQLMinMemory</td>"
Add-Content $fileName "<td width='10%' align='center'>Memory Available MBytes</td>"
Add-Content $fileName "<td width='10%' align='center'>Buffer Cache Hit Ratio</td>"
Add-Content $fileName "<td width='10%' align='center'>PLE</td>"
Add-Content $fileName "</tr>"
}

Function writeHtmlFooter
{
param($fileName)

Add-Content $fileName "</body>"
Add-Content $fileName "</html>"
}

Function writeMemoryInfo
{
param($filename,$csname,$TotalVirtualMemorySize,$TotalVisibleMemorySize,$FreePhysicalMemory,$FreeVirtualMemory,$FreeSpaceInPagingFiles,$NumberofProcesses,$NumberOfUsers,$PageFile,$initialSize,$MaxSize,$SQLMaxMemory, $SQLMinMemory ,$mAvailableMBytes, $Buffercachehitratio, $PLE )
 Add-Content $fileName "<tr>"
 Add-Content $fileName "<td>$csname </td>"
 Add-Content $fileName "<td>$TotalVirtualMemorySize </td>"
 Add-Content $fileName "<td>$TotalVisibleMemorySize</td>"
 Add-Content $fileName "<td>$FreePhysicalMemory </td>"
 Add-Content $fileName "<td>$FreeVirtualMemory </td>"
 Add-Content $fileName "<td>$FreeSpaceInPagingFiles </td>"
 Add-Content $fileName "<td>$NumberofProcesses </td>"
 Add-Content $fileName "<td>$NumberOfUsers</td>"
 Add-Content $fileName "<td>$PageFile</td>"
 Add-Content $fileName "<td>$initialSize</td>"
 Add-Content $fileName "<td>$MaxSize</td>"
 Add-Content $fileName "<td>$SQLMaxMemory</td>"
 Add-Content $fileName "<td>$SQLMinMemory</td>"
 Add-Content $fileName "<td>$mAvailableMBytes</td>"
 Add-Content $fileName "<td>$Buffercachehitratio</td>"
 Add-Content $fileName "<td>$PLE</td>"
 
 Add-Content $fileName "</tr>"
}

Function sendEmail  

 { 
param($from,$to,$subject,$smtphost,$htmlFileName)  

$body = Get-Content $htmlFileName 
$body = New-Object System.Net.Mail.MailMessage $from, $to, $subject, $body 
$body.isBodyhtml = $true
$smtpServer = $MailServer
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($body)

    

 }  


writeHtmlHeader $MemoryFileName
 Add-Content $MemoryFileName "<table width='100%'><tbody>"
 Add-Content $MemoryFileName "<tr bgcolor='#CCCCCC'>"
 Add-Content $MemoryFileName "<td width='100%' align='center' colSpan=16><font face='tahoma' color='#003399' size='2'><strong> Memory Usage Details</strong></font></td>"
 Add-Content $MemoryFileName "</tr>"

 writeTableHeader $MemoryFileName

foreach ($svr in get-content "\\hqdbsp18\f$\PowerSQL\Server.txt"){

$page=Get-WMIObject Win32_PageFileSetting -Computer $svr|  select __Server, Name, InitialSize, MaximumSize
$dp = Get-WmiObject -Class Win32_OperatingSystem  -ComputerName $svr | select  CSName,
@{name="TotalVirtualMemorySize";expression={($_.TotalVirtualMemorySize/1024).tostring("N0")}},
@{name="TotalVisibleMemorySize";expression={($_.TotalVisibleMemorySize/1024).tostring("N0")}},
@{name="FreePhysicalMemory";expression={($_.FreePhysicalMemory/1024).tostring("N0")}},
@{name="FreeVirtualMemory";expression={($_.FreeVirtualMemory/1024).tostring("N0")}},
@{name="FreeSpaceInPagingFiles";expression={($_.FreeSpaceInPagingFiles/1024).tostring("N0")}},
NumberofProcesses,
NumberOfUsers

$srv = new-object ('Microsoft.SqlServer.Management.Smo.Server') ($svr)
write-host $srv.Configuration.MaxServerMemory.RunValue 
write-host $srv.Configuration.MinServerMemory.RunValue 


$counters = @("\Memory\Available MBytes",
 "\Memory\Pages/sec",
 "\SQLServer:Buffer Manager\Buffer cache hit ratio",
 "\SQLServer:Buffer Manager\Lazy writes/sec",
 "\SQLServer:Buffer Manager\Page life expectancy"
  ) 
 $collections = Get-Counter -ComputerName $svr -Counter $counters -SampleInterval 5 -MaxSamples 1
 Write-Output $collections 
 foreach ($collection in $collections) 
    {
     $sampling = $collection.CounterSamples | Select-Object -Property TimeStamp, Path, Cookedvalue 
     foreach($sam in $sampling)
        {
            if ($sam.Path -like "*\Memory\Available MBytes*") {
                $mAvailableMBytes=$sam.CookedValue
                }
            elseif ($sam.Path -like "*Buffer Manager\Buffer cache hit ratio*") {
                $Buffercachehitratio=$sam.CookedValue
            }
            elseif ($sam.Path -like "*Page life expectancy*") {
                $PLE=$sam.CookedValue}
        }
    }
write-host $mAvailableMBytes $Buffercachehitratio $PLE


Write-Host  $dp.csname $dp.TotalVirtualMemorySize $dp.TotalVisibleMemorySize $dp.FreePhysicalMemory $dp.FreeVirtualMemory $dp.FreeSpaceInPagingFiles $dp.NumberofProcesses $dp.NumberOfUsers  $page.InitialSize $page.Name $page.MaximumSize $srv.Configuration.MaxServerMemory.RunValue $srv.Configuration.MinServerMemory.RunValue  $mAvailableMBytes $Buffercachehitratio $PLE
writeMemoryInfo $MemoryFileName $dp.csname $dp.TotalVirtualMemorySize $dp.TotalVisibleMemorySize $dp.FreePhysicalMemory $dp.FreeVirtualMemory $dp.FreeSpaceInPagingFiles $dp.NumberofProcesses $dp.NumberOfUsers  $page.Name $page.InitialSize $page.MaximumSize $srv.Configuration.MaxServerMemory.RunValue $srv.Configuration.MinServerMemory.RunValue $mAvailableMBytes $Buffercachehitratio $PLE

 }


  Add-Content $MemoryFileName "</table>" 

writeHtmlFooter $MemoryFileName 
$date = ( get-date ).ToString('yyyy/MM/dd')
sendEmail [email protected] [email protected] "Memory Usage Report - $Date" $MailServer $MemoryFileName
 

[/expand]

Keluaran

Menutup

Sekarang setelah Anda mempelajari beberapa hal baru tentang manajemen memori SQL Server, Anda akan lebih memahami sumber daya SQL Server.

Jika ada RAM yang memadai di server, halaman data dapat bertahan lebih lama di kumpulan buffer yang akibatnya menghasilkan pengurangan drastis dalam kebutuhan I/O.

Meskipun dalam kebanyakan kasus, Administrator Basis Data mengandalkan pengaturan memori default, kita perlu memahami bahwa kebutuhan memori internal bergantung pada beban kerja instance.

Artikel ini adalah panduan tingkat tinggi dari memori SQL Server dan internalnya. Selain itu, ini mencakup berbagai alasan di balik kemacetan kinerja yang disebabkan oleh tidak menyetel memori maksimal.

Saya telah menyertakan petunjuk langkah demi langkah untuk menyiapkan dan mengonfigurasi laporan memori. Langkah-langkah tentang cara mengatur memori SQL juga disertakan. Selanjutnya, kami membahas berbagai komponen SQL yang berkontribusi pada penggunaan memori yang tersedia di lingkungan SQL Server.

Satu hal yang perlu diingat adalah bahwa alokasi dan de-alokasi memori memperlambat startup. Oleh karena itu, jika Anda memiliki beberapa aplikasi yang berhenti dan memulai di server yang sama, hal itu dapat memengaruhi kinerja. Demikian pula, jika ada beberapa aplikasi lain yang berjalan di server yang sama, pengaturan memori server minimum dan memori server maksimum menjadi lebih penting untuk memastikan kinerja yang optimal.

Itu saja untuk saat ini…

Referensi

  1. Memantau Penggunaan Memori
  2. Pentingnya Setting Max Server Memory di SQL Server dan Cara Settingnya
  3. Opsi Konfigurasi Server Memori Server

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara mendapatkan daftar semua tabel dalam database menggunakan TSQL?

  2. Menggunakan INSERT INTO dari SQL Server Untuk Mengubah Data Salesforce

  3. Batasan SQL DEFAULT untuk Menyisipkan Kolom dengan Nilai Default ke Tabel SQL Server

  4. Tipe Data VARCHAR dan NVARCHAR di SQL Server

  5. Cara membuat Batasan Kunci Asing Dengan ON UPDATE CASCADE di SQL Server - Tutorial SQL Server / TSQL Bagian 79