Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Zrozumienie znaczenia ustawienia pamięci w SQL Server

Pamięć jest jednym z zasobów tworzących trójkąt wydajności — dwoma pozostałymi są procesor i pamięć masowa. Jeśli jeden zostanie trafiony, dwa pozostałe biorą na siebie obciążenie, aby spróbować doprowadzić wydajność do akceptowalnego poziomu, ale zawsze jest kompromis. Wszelkie transakcje, których nie można zatwierdzić w pamięci, zostaną przekazane do podsystemu dyskowego przez SQL Server. Powoduje to wąskie gardło wydajności. Dlatego statystyki oczekiwania mogą pomóc w identyfikacji problemów z wydajnością na serwerze SQL.

W tym artykule omówiono następujące tematy:

  1. Zrozumienie wewnętrznych ustawień i konfiguracji pamięci SQL Server
  2. Pamięć SQL Server i jej wpływ na wydajność bazy danych i aplikacji
  3. Omów różne składniki SQL Server, które przyczyniają się do wykorzystania pamięci
  4. Najlepsze praktyki i zalecenia dotyczące rozmiaru pamięci
  5. Raport pamięci na wielu serwerach
  6. I więcej…

Wewnętrzne elementy zarządzania pamięcią

SQL Server ma jednostkę zarządzania pamięcią, która wykonuje zautomatyzowane dynamiczne zarządzanie pamięcią w oparciu o obciążenie systemu. Ta pamięć jest ulotną przestrzenią, która ma kluczowe znaczenie dla dzisiejszych potrzeb biznesowych – technicznych, których odpowiedni rozmiar ma kluczowe znaczenie dla optymalnej wydajności aplikacji.

Jednak wszyscy wiemy, że podczas konfigurowania serwera rozmiar zawiera pewne wartości domyślne. w niektórych przypadkach wkrótce dowiadujemy się, że SQL Server wykorzystuje prawie całą pamięć na serwerze, mimo że nie ma widocznej aktywności w bazach danych, co rodzi pytania:Czy wartości domyślne są nieprawidłowe? Jeśli tak, jaki powinien być odpowiedni rozmiar?

Zarządzanie pamięcią w programie SQL Server działa na algorytmie Fill-and-Flush. Wartości domyślne nie ograniczają wzrostu zużycia pamięci, chyba że pojawi się żądanie z systemu operacyjnego.

Rozmiar zależy od różnych elementów systemu — w wielu przypadkach ustawienie go między 70% a 80% jest dobrym punktem wyjścia. Następnie powinieneś go również monitorować, aby zobaczyć, czego jeszcze możesz brakować i czy powinieneś dostosować ustawienie. Jeśli masz inne usługi na serwerze SQL (naprawdę nie powinieneś), być może będziesz musiał zostawić więcej, zwłaszcza jeśli te usługi są świniami pamięci. Rozważ ponowne sprawdzenie ustawień pamięci instancji SQL w dowolnym z poniższych scenariuszy:

  • Brak odpowiedzi systemu operacyjnego
  • Wyczerpanie aplikacji
  • Operacje tworzenia kopii zapasowych, które wymagają dużych buforów pamięci
  • Obiekty zoptymalizowane w pamięci
  • Indeksy magazynu kolumn, ponieważ wymagają dużej ilości pamięci do obsługi indeksów.

Ustawienie pamięci w SQL Server jest dość proste. Możesz zmienić wartość za pomocą sp_configure lub GUI SSMS. Jest to opcja online, ale pamiętaj, że ustawienie lub zresetowanie tych wartości może spowodować przetasowanie niektórych obiektów wewnętrznej pamięci podręcznej, co spowoduje, że system będzie działał nieco wolniej.

sp_configure 'maksymalna pamięć serwera (MB)',

W tym przypadku liczba „2147483647” oznacza, że ​​SQL Server nie ma górnego limitu i wykorzysta całą pamięć na serwerze.

Minimalna pamięć serwera:minimalna pamięć serwera jako wartość minimalna; SQL Server będzie przydzielać pamięć do własnego użytku, dopóki nie osiągnie ustawienia minimalnej pamięci serwera. Następnie utrzyma przynajmniej taką ilość użytecznej pamięci.

Maksymalna pamięć serwera:w taki sam sposób, w jaki minimalna pamięć serwera zapewnia poziom, maksymalna pamięć serwera zapewnia pułap.

Minimalny i maksymalny poziom pamięci to dolny i górny limit ilości pamięci dozwolonej przez pulę buforów. Pula buforów to największy fragment pamięci używany przez program SQL Server. Poniżej znajdują się składniki SQL Server w instancji SQL, które wykorzystują pamięć z puli buforów

  • Pamięć podręczna stron bazy danych
  • Wewnętrzne pamięci podręczne dzienników
  • Pamięć podręczna procedur lub pamięć podręczna planu zapytań
  • Przestrzeń obciążenia zapytania
  • Blokady (przyznanie pamięci)
  • Kontekst połączenia
  • Optymalizacja zapytań
  • Struktury danych na poziomie systemu

Wartości ważnych metryk, takich jak dostępne Mbajty, strony/s, współczynnik trafień w buforze bufora, PLE itp. określają wydajność SQL Server.

Współczynnik trafień w pamięci podręcznej bufora jest specyficzny dla każdej aplikacji. 90% jest zwykle uważane za pożądane. Oznacza to, że pamięć podręczna obsługiwała ponad 90% żądań, co jest dobrą rzeczą. Jeśli wartość jest niższa, dodaj więcej pamięci, aż będzie stale wyższa niż 90%.

Dostępne bajty to nic innego jak wskazanie, ile pamięci jest dostępnej do użycia. Licznik Strony/s pokazuje, ile stron zostało pobranych z dysku lub zapisanych na dysku, w obu przypadkach z powodu twardych błędów stron.

PLE to skrót od Page Life Expectancy, który wskazuje, przez ile sekund strona pozostanie w puli.

Na przykład

$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
   }

Zalecenia i najlepsze praktyki

Przyjrzyjmy się teraz pokrótce technikom określania rozmiaru pamięci.

  1. 1 GB pamięci zarezerwowane dla systemu operacyjnego
  2. 1 GB na każde 4 GB pamięci RAM po początkowych 4 GB, do 16 GB pamięci RAM
  3. 1 GB każdy na każde 8 GB w ponad 16 GB pamięci RAM

Na przykład, jeśli masz serwer bazy danych o pojemności 32 GB RAM, pamięć przekazywana systemowi operacyjnemu będzie wynosić

  1. 1 GB, minimalna alokacja
  2. + 3 GB, ponieważ 16 GB – 4 GB =12 GB; 12 GB podzielone przez 4 GB (każde 4 GB to 1 GB) to 3 GB.
  3. + 2 GB, ponieważ 32 GB – 16 GB =16 GB; 16 podzielone przez 8 (każde 8 GB po 16 GB to 1 GB) to 2 GB

Łącznie więc dla serwera z 32 GB pamięci RAM zarezerwowane zostanie 7 GB na system operacyjny. Jest to maksymalna pamięć przydzielona do programu SQL Server powinna wynosić 25 GB. Podobnie, w przypadku serwera 64 GB, 10 GB powinno być zarezerwowane na system operacyjny, a 54 GB powinno być przeznaczone na serwer SQL.

Wszyscy w pewnym momencie słyszeliśmy lub używaliśmy Instrumentacji zarządzania Windows (WMI). W WMI istnieje kilka klas, które pozwalają nam wydobyć informacje o sprzęcie, zainstalowanym oprogramowaniu, systemie operacyjnym, a nawet rejestrze. Możemy nawet modyfikować ustawienia i wykonywać działania w tych aspektach.

Klasa win32_OperatingSystem to klasa WMI, która zawiera wszystkie niezbędne informacje o aktywnym system operacyjny (na przykład w przypadku podwójnego rozruchu). Ta klasa może być również użyta do uzyskania ilości pamięci przydzielonej systemowi operacyjnemu. Oto niektóre z obiektów, które klasa może zwrócić, a które mogą nam pomóc (pamięć jest mierzona w kilobajtach przez tę klasę):

  • TotalVisibleMemorySize :To pole pokazuje całkowitą pamięć fizyczną dostępną dla systemu operacyjnego. Niedostępne fragmenty pamięci mogą spowodować wyświetlenie mniejszej liczby niż zainstalowana.
  • Bezpłatna pamięć fizyczna :To mówi nam, jaka ilość pamięci fizycznej jest wolna.
  • TotalVirtualMemorySize :Jest to całkowita pamięć wirtualna dostępna dla systemu operacyjnego. Obejmuje to pamięć fizyczną zainstalowaną na komputerze wraz z rozmiarem pliku stronicowania.
  • Bezpłatna pamięć wirtualna :Podobny do FreePhysicalMemory, ale zawiera również wolne miejsce w pamięci stronicowania.
$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 

Możemy pobrać informacje o pliku strony za pomocą klasy Win32_PageFileSetting WMI.

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

Poniższe zapytanie podaje szczegóły użycia pamięci wysokiego poziomu przez instancję 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;

Przygotuj skrypt

Zintegrujmy wyżej wymienione trzy wyjścia w jedno wyjście pamięci:

  1. Struktury pamięci wewnętrznej SQL przy użyciu licznika
  2. Dostępna pamięć wirtualna i fizyczna przy użyciu obiektu WMI
  3. Ustawienie pliku strony za pomocą WMI

Przygotowanie treści HTML polega na wpisaniu wartości z różnych sekcji skryptu, między właściwymi tagami.

Skrypt może budować poprawne znaczniki HTML. Poniżej przedstawiono funkcje używane w skrypcie.

  1. writeHTMLHeader:ta funkcja służy do generowania nagłówka i definiowania stylu pliku HTML.
  2. writetableFooter:definiuje zamykające znaczniki HTML.
  3. writeTableHeader:definiuje trzynastokolumnowy nagłówek wyjściowy dla pliku HTML
  4. writeMemoryInfo:jest to funkcja, która łączy dwa wyjścia klasy WMI. Dane wyjściowe Win32_PageFileSetting, Win32_OperatingSystem i SMO SQL są przekazywane jako argumenty tej funkcji. Wartości można również dalej przekształcać lub manipulować w tej sekcji.
  5. Sekcja poczty e-mail

[rozwiń tytuł=”Kod”]

# 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
 

[/rozwiń]

Wyjście

Zawijanie

Teraz, gdy nauczyłeś się kilku nowych rzeczy na temat zarządzania pamięcią SQL Server, lepiej zrozumiesz zasoby SQL Server.

Jeśli na serwerze jest wystarczająca ilość pamięci RAM, strony danych mogą mieć dłuższą żywotność w puli buforów, co w konsekwencji powoduje drastyczne zmniejszenie potrzeb we/wy.

Chociaż w większości przypadków administratorzy baz danych polegają na domyślnych ustawieniach pamięci, musimy zrozumieć, że wewnętrzne wymagania dotyczące pamięci zależą od obciążenia instancji.

Ten artykuł to ogólny przewodnik dotyczący pamięci programu SQL Server i jej elementów wewnętrznych. Obejmuje również różne przyczyny wąskich gardeł wydajności spowodowanych nieustawieniem maksymalnej pamięci.

Dołączyłem instrukcje krok po kroku, jak skonfigurować i skonfigurować raport pamięci. Zawarto również instrukcje dotyczące ustawiania pamięci SQL. Ponadto omówiliśmy różne komponenty SQL, które przyczyniają się do wykorzystania dostępnej pamięci w środowisku SQL Server.

Należy pamiętać, że alokacja i cofanie alokacji pamięci spowalniają uruchamianie. Dlatego jeśli kilka aplikacji zatrzymuje się i uruchamia na tym samym serwerze, może to wpłynąć na wydajność. Podobnie, jeśli na tym samym serwerze działa kilka innych aplikacji, ustawienie minimalnej pamięci serwera i maksymalnej pamięci serwera staje się ważniejsze, aby zapewnić optymalną wydajność.

To wszystko na teraz…

Referencje

  1. Monitorowanie wykorzystania pamięci
  2. Ważne ustawienie maksymalnej pamięci serwera w SQL Server i jak to ustawić
  3. Opcje konfiguracji serwera pamięci serwera

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Klucz obcy do klucza złożonego

  2. Znajdź znaki spoza zestawu ASCII w kolumnach varchar za pomocą SQL Server

  3. Jak bezpiecznie przechowywać hasła w bazie danych?

  4. Punkty kontrolne bazy danych w SQL Server

  5. Jak wybrać dane tabeli z innej bazy danych w SQL Server?