SQL Memory

Check

SELECT physical_memory_in_use_kb/1024    AS [Used by SQL (MB)],

       total_physical_memory_kb/1024     AS [Physical Memory (MB)], 

       available_physical_memory_kb/1024 AS [Available Memory (MB)], 

       total_page_file_kb/1024           AS [Total Page File (MB)], 

       available_page_file_kb/1024       AS [Available Page File (MB)], 

       system_cache_kb/1024              AS [System Cache (MB)],

       system_memory_state_desc          AS [System Memory State]

  FROM sys.dm_os_sys_memory,

       sys.dm_os_process_memory

  WITH (NOLOCK) OPTION (RECOMPILE);

https://dba.stackexchange.com/questions/213010/memory-usage-by-sql-server

SELECT c.name, c.value, c.value_in_use 

  FROM sys.configurations c 

 WHERE c.[name] IN ('max server memory (MB)','min server memory (MB)');

List Cached Data Per Object in Memory (1)...

SELECT COUNT (1) * 8 / 1024 AS MBUsed, 

    OBJECT_SCHEMA_NAME(object_id) SchemaName, 

name AS TableName, index_id   

FROM sys.dm_os_buffer_descriptors AS bd   

    INNER JOIN   

    (  

        SELECT object_name(object_id) AS name   

            ,index_id ,allocation_unit_id, object_id  

        FROM sys.allocation_units AS au  

            INNER JOIN sys.partitions AS p   

                ON au.container_id = p.hobt_id   

                    AND (au.type = 1 OR au.type = 3)  

        UNION ALL  

        SELECT object_name(object_id) AS name     

            ,index_id, allocation_unit_id, object_id  

        FROM sys.allocation_units AS au  

            INNER JOIN sys.partitions AS p   

                ON au.container_id = p.partition_id   

                    AND au.type = 2  

    ) AS obj   

        ON bd.allocation_unit_id = obj.allocation_unit_id  

WHERE database_id = DB_ID()  

GROUP BY OBJECT_SCHEMA_NAME(object_id), name, index_id   

ORDER BY COUNT (*) * 8 / 1024 DESC

GO

Buffer Pool

-- Note: querying sys.dm_os_buffer_descriptors

-- requires the VIEW_SERVER_STATE permission.


DECLARE @total_buffer INT;


SELECT @total_buffer = cntr_value

FROM sys.dm_os_performance_counters 

WHERE RTRIM([object_name]) LIKE '%Buffer Manager'

AND counter_name = 'Database Pages';


;WITH src AS

(

  SELECT 

  database_id, db_buffer_pages = COUNT_BIG(*)

  FROM sys.dm_os_buffer_descriptors

  --WHERE database_id BETWEEN 5 AND 32766

  GROUP BY database_id

)

SELECT

[db_name] = CASE [database_id] WHEN 32767 

THEN 'Resource DB' 

ELSE DB_NAME([database_id]) END,

db_buffer_pages,

db_buffer_MB = db_buffer_pages / 128,

db_buffer_percent = CONVERT(DECIMAL(6,3), 

db_buffer_pages * 100.0 / @total_buffer)

FROM src

ORDER BY db_buffer_MB DESC;

USE mydb;

GO


;WITH src AS

(

  SELECT

  [Object] = o.name,

  [Type] = o.type_desc,

  [Index] = COALESCE(i.name, ''),

  [Index_Type] = i.type_desc,

  p.[object_id],

  p.index_id,

  au.allocation_unit_id

  FROM sys.partitions AS p

  INNER JOIN sys.allocation_units AS au ON p.hobt_id = au.container_id

  INNER JOIN sys.objects AS o ON p.[object_id] = o.[object_id]

  INNER JOIN sys.indexes AS i ON o.[object_id] = i.[object_id] AND p.index_id = i.index_id

  WHERE

  au.[type] IN (1,2,3)

  AND o.is_ms_shipped = 0

)

SELECT

src.[Object],

src.[Type],

src.[Index],

src.Index_Type,

buffer_pages = COUNT_BIG(b.page_id),

buffer_mb = COUNT_BIG(b.page_id) / 128

FROM src

INNER JOIN sys.dm_os_buffer_descriptors AS b ON src.allocation_unit_id = b.allocation_unit_id

WHERE

b.database_id = DB_ID()

GROUP BY

src.[Object],

src.[Type],

src.[Index],

src.Index_Type

ORDER BY

buffer_pages DESC;

Plan Cache

Min/Max Memory

Set min/max memory - calculate as below or leave at least 2GB for OS (skip this step on SQL Express)

Some settings for common configurations is documented in the "Change Max and Min Server Memory" section later.

3.5.2 Memory ReservationWhen achieving adequate performance is the primary goal, consider setting the memory reservation equal to the provisioned memory. This will eliminate the possibility of ballooning or swapping from happening and will guarantee that the virtual machine gets only physical memory. When calculating the amount of memory to provision for the virtual machine, use the following formulas:
VM Memory = SQL Max Server Memory + ThreadStack + OS Mem + VM OverheadThreadStack = SQL Max Worker Threads * ThreadStackSize SQL Max Server Memory = VM Memory - SQL Max Worker Threads * ThreadStackSize - OS Mem - VM OverheadSQL Min Server Memory = SQL Max Server Memory - 2048MB
https://www.vmware.com/content/dam/digitalmarketing/vmware/en/pdf/solutions/sql-server-on-vmware-best-practices-guide.pdf
NOTE that if you are running one or more applications on the same virtual machine as the SQL Server instance (not recommended) then you will also need to take into account the memory requirements of that application when setting SQL Max Server Memory.

VM Memory

SELECT total_physical_memory_kb/1024 AS [Physical Memory (MB)]

  FROM sys.dm_os_sys_memory

SQL Max Worker Threads

SELECT cpu_count AS [Logical CPU Count], 

       hyperthread_ratio AS [Hyperthread Ratio], 

       cpu_count/hyperthread_ratio AS [Physical CPU Count],

       RIGHT(SUBSTRING(@@VERSION, CHARINDEX('<',@@VERSION),4),3) Architecture

  FROM sys.dm_os_sys_info

OPTION (RECOMPILE);

The following table shows the automatically configured maximum number of threads...

MS-SQL Config

ThreadStackSize

The following table shows the ThreadStackSize for each Architecture...

https://thomaslarock.com/2013/01/how-to-determine-if-you-are-running-a-32-bit-version-of-sql-server-on-a-64-bit-os/
MS-SQL Config

OS Mem

1024MB for every 4 CPU Cores

SELECT (cpu_count/4)*1024 as OS_Mem_MB

  FROM sys.dm_os_sys_info

VM Overhead

SELECT CEILING((20.29+((cpu_count-1)*3.99)+(((((total_physical_memory_kb/1024)+1)/256)-1)*1.89)) AS vm_overhead_MB

  FROM sys.dm_os_sys_info,

       sys.dm_os_sys_memory

Change Max and Min Server Memory

sp_configure 'show advanced options', 1;

GO

RECONFIGURE

go

For a server with 4 vCPUs and 8GB of memory...

-- SQL Max Server Memory = 8192 - (512*2) - 1024 - 91 = 6053

-- SQL Min Server Memory = 6053 - 2048 = 4005


EXEC sys.sp_configure N'min server memory (MB)', N'4005'

go

EXEC sys.sp_configure N'max server memory (MB)', N'6053'

GO

RECONFIGURE WITH OVERRIDE

For a server with 4 vCPUs and 16GB of memory...

-- SQL Max Server Memory = 16384 - (512*2) - 1024 - 152 = 14184

-- SQL Min Server Memory = 14184 - 2048 = 12136


EXEC sys.sp_configure N'min server memory (MB)', N'12136'

go

EXEC sys.sp_configure N'max server memory (MB)', N'14184'

GO

RECONFIGURE WITH OVERRIDE

Memory in Virtual Environments

Bibliography & References

https://dba.stackexchange.com/questions/213010/memory-usage-by-sql-serverhttps://www.vmware.com/content/dam/digitalmarketing/vmware/en/pdf/solutions/sql-server-on-vmware-best-practices-guide.pdfhttps://docs.microsoft.com/en-us/sql/database-engine/configure-windows/server-memory-server-configuration-options?view=sql-server-2017
https://docs.microsoft.com/pl-pl/previous-versions/sql/sql-server-2008-r2/ms187024(v=sql.105)https://social.msdn.microsoft.com/Forums/sqlserver/en-US/cbab12c0-94e8-4a8d-83fa-82f76e0d15f9/how-to-find-number-of-cores-through-tsql?forum=transactsqlhttps://thomaslarock.com/2013/01/how-to-determine-if-you-are-running-a-32-bit-version-of-sql-server-on-a-64-bit-os/
(1) https://blog.sqlauthority.com/2021/03/31/sql-server-cached-data-per-object-in-memory/https://dba.stackexchange.com/questions/312725/allocating-more-memory-than-is-available-for-the-installed-sql-server-edition/312749#312749https://dba.stackexchange.com/questions/258005/virtualized-sql-server-hits-100-cpu-and-0-active-memoryhttps://www.mssqltips.com/sqlservertip/2304/how-to-identify-microsoft-sql-server-memory-bottlenecks/
https://www.davidklee.net/2015/05/22/vm-memory-counters-lie-for-sql-server-vms/
Buffer Poolhttps://www.mssqltips.com/sqlservertip/2393/determine-sql-server-memory-use-by-database-and-object/https://www.mssqltips.com/sqlservertip/2194/trending-buffer-pool-performance-using-dmv-sysdmosperformancecounters/
Plan Cachehttps://www.mssqltips.com/sqlservertip/2196/analyzing-sql-server-plan-cache-performance-using-dmvs/
06:22 What bad things can happen if SQL Server VM max server memory setting is left unconfigured?