SQL Server Express e utilizzo della memoria

L’edizione Express di SQL Server è gratuita, ma ha delle limitazioni tra cui quella relativa alla memoria utilizzata come indicato nel seguenti:

Di seguito quanto viene riportato per ogni versione:

  • SQL Server 2016
    Maximum memory for buffer pool per instance of SQL Server Database Engine = 1410 MB
  • SQL Server 2014, SQL Server 2012
    Maximum memory utilized (per instance of SQL Server Database Engine) = 1 GB
  • SQL Server 2008 R2
    Maximum memory utilized
Il limite circa l’utilizzo della memoria, come più precisamente specificato nel link relativo a SQL Server 2016, si riferisce al buffer pool ovvero alla cache in memoria delle pagine del database, a riguardo si veda

Buffer Management:

“The primary purpose of a SQL Server database is to store and retrieve data, so intensive disk I/O is a core characteristic of the Database Engine. And because disk I/O operations can consume many resources and take a relatively long time to finish, SQL Server focuses on making I/O highly efficient. Buffer management is a key component in achieving this efficiency. The buffer management component consists of two mechanisms: the buffer manager to access and update database pages, and the buffer cache (also called the buffer pool), to reduce database file I/O.”

Questo però non significa che un’istanza di SQL Server Express occuperà un massimo di 1GB per le versioni 2008 R2, 2012, 2014 e 1040 MB per la versione 2016.

Il motivo sta nel fatto che in SQL Server il buffer cache non è l’unica funzionalità a consumare memoria, per vedere tutte le funzionalità che impiegano la memoria è possibile usare la vista di sistema sys.dm_os_memory_clerks, di seguito una query per visualizzare in SQL Server 2012 e successivi le funzionalità che occupano più di un MB in memoria:

select type,
sum(pages_kb)/1024 as [Memory utilized in MB]  from sys.dm_os_memory_clerks
  group by type
  having sum(pages_kb)/1024 > 0
  order by [Memory utilized in MB] desc

di seguito invece il risultato della query su di un SQL Server 2014, ovviamente i risultato dipendono dallo stato di utilizzo del DBMS:

image

Come riportato ad esempio nel post SQL Server 2014 Express Actual Memory Limit in SQL Server 2014 l’occupazione di memoria può crescere oltre i 1600 MB, mentre nel post Squishy Limits in SQL Server Express Edition in SQL Server 2012 l’occupazione di memoria può arrivare a 1500 MB.

Nel post SQL Server 2016 SP1: Know your limits sul blog del team di sviluppo di SQL Server viene appunto precisato che il limite riportato nella documentazione era relativo solo al buffer pool:

“In the past, the memory limits defined in table above in the SQL Server editions page for lower editions were referred to as Maximum memory utilized per instance which did not accurately reflect the true limits. The memory limit defined for lower editions of SQL Server is essentially Maximum buffer pool memory limit. In simpler terms, buffer pool memory in SQL Server is a memory cache responsible for caching data and index pages for the entire instance. The rest of the caches in the SQL Server memory (procedure cache, thread stack, backup buffers etc) consumes memory outside buffer pool memory. The memory consumed by caches outside buffer pool is not restricted by above memory limits and can grow up to limits defined by “max server memory”. This is not specific to SQL Server 2016 SP1 and is also applicable to earlier releases of SQL Server as well.”

Sempre nel post SQL Server 2016 SP1: Know your limits viene poi precisato che oltre al Maximum memory for buffer pool si aggiungono il Maximum memory for Columnstore segment e il Maximum memory-optimized data size per database in SQL Server Database Engine:

image

“The limits for In-Memory OLTP data is per database. If you would like to estimate memory size required for your data, please refer to Estimate Memory Requirements for Memory-Optimized Tables.

The limits for Columnstore segment cache is per SQL Server instance across all the databases in the instance.

Like earlier versions of SQL Server, there are still no quota limits defined for caches other than buffer pool, In-Memory OLTP data and Columnstore segment cache. The memory consumed by other caches will still be solely restricted by max server memory (if capped) on SQL Server or memory on the server if max server memory is uncapped.”

Quindi in SQL Server Express 2016 SP1 è possibile che vengano utilizzati fino 2114 MB di memoria per buffer pool, Columnstore segment cache e i Maximum memory-optimized data, inoltre possono esserci anche altre funzionalità che occupano memoria (thread stack, backup buffers etc).

Se è necessario imporre un limite di occupazione della memoria è necessario impostare in SQL Server l’opzione di configurazione max server memory che per default è impostata a 2.147.483.647 MB, a riguardo si veda Server Memory Server Configuration Options:

“max server memory controls the SQL Server memory allocation, including the buffer pool, compile memory, all caches, qe memory grants, lock manager memory, and clr memory (essentially any memory clerk found in sys.dm_os_memory_clerks). Memory for thread stacks, memory heaps, linked server providers other than SQL Server, and any memory allocated by a non SQL Server DLL are not controlled by max server memory.”

image