In this survey I'd like you to run some code and then send me the results (and I'm sure someone will put together a PowerShell script to make it easy to run on multiple instances).
I want to know how much of your precious server memory is being wasted storing empty space on data file pages. I'm sure you'll be interested in it too!
Here's the code (works on 2005+):
SELECT
COUNT (*) * 8 / 1024 AS MBUsed,
SUM (CONVERT (BIGINT, free_space_in_bytes)) / (1024 * 1024) AS MBEmpty
FROM sys.dm_os_buffer_descriptors;
GO
[Edit: forgot that many systems have way more memory than my 16GB laptop, so updated code above uses BIGINT now.
And here's a PowerShell script courtesy of Nic Cain, assuming server list in c:\temp\serverlist.txt:
$SQLQuery = 'SELECT
COUNT (*) * 8 / 1024 AS MBUsed,
SUM (CONVERT (BIGINT, free_space_in_bytes)) / (1024 * 1024) AS MBEmpty
FROM sys.dm_os_buffer_descriptors;
GO'$servers = get-content c:\temp\serverlist.txt
foreach ($srv in $servers)
{
invoke-sqlcmd -Server $srv -Database master -Query $SQLQuery
}
/Edit]
Send me the results for as many systems as you can, preferably production systems – either as a comment on this post, in email, or in a spreadsheet in email.
I'll collect all the results and explain what this means, how to drill in further, and what you can do about it in a week or two.
Thanks!
109 thoughts on “Survey: how much server memory is being wasted? (code to run)”
3994 used
171 empty
MBUsed MBEmpty
945 40
MBUsed MBEmpty
1542 105
Here’s what I get :):
Msg 8115, Level 16, State 2, Line 1
Arithmetic overflow error converting expression to data type int.
I assume getting "Arithmetic Overflow" is bad? :)
(changed the free_space_in_bytes to (convert(bigint,free_space_in_bytes))
Here’s from several OLTP servers
MBUsed MBEmpty
28007 4187
21153 8366
19446 3703
26287 8238
23837 3768
5084 1100
21325 3694
19552 11382
SQL Server 2008 R2 with 32GB of memory
Original query:
Msg 8115, Level 16, State 2, Line 1
Arithmetic overflow error converting expression to data type int.
Modified query
SELECT
COUNT (*) * 8 / 1024 AS MBUsed,
SUM (CAST(free_space_in_bytes as bigint)) / (1024 * 1024) AS MBEmpty
FROM sys.dm_os_buffer_descriptors;
MBUsed MBEmpty
23846 3421
3995
171
MBUsed MBEmpty
11815 1021
3371 333
936 175
Server1 590 70
Server2 612 145
Server3 887 70
Server4 6232 451
Server5 7415 559
Server6 12270 482
used 3631
empty 963
A couple of numbers
MBUsed MBEmpty
21810 4114
23718 3314
1002 282
3808 1211
MBUsed MBEmpty
21623 2325
MbUsed MBEmpty
15729 2304
4869 176
6772 1807
Environment 1:
MBUsed MBEmpty
5443 1997
Environment 2:
MBUsed MBEmpty
1892 182
Environment 3:
MBUsed MBEmpty
2926 234
–25006 2832 Server 1
–10823 1286 Server 2
MBUsed MBEmpty
———– ——————–
15712 2414
4866 177
568 144
MBUsed MBEmpty
4311 1491
4207 940
1490 223
43474 5380
MBUsed MBEmpty
38202 9493
38152 7928
28062 2225
MBUsed MBEmpty
43487 4896
2928 497
712 194
624 57
496 201
200 101
140 59
9 2
2 1
Server Name MBUsed MBEmpty
Dev_2005_1 594 337
Dev_2005_2 483 306
Dev_2005_3 2933 765
Dev_2005_4 620 295
Dev_2005_5 10976 1870
Dev_2008_1 78 23
Dev_2008_2 237 52
Dev_2008_3 5022 1504
Dev_2008_4 7208 1837
Dev_2008_5 4254 123
Prod_2005_1 974 261
Prod_2005_2 23 11
Prod_2005_3 416 81
Prod_2005_4 92 41
Prod_2005_5 593 356
Prod_2005_6 722 177
Prod_2005_7 639 81
Prod_2005_8 2079 440
Prod_2005_9 604 207
Prod_2005_10 202 118
Prod_2005_11 2464 460
Prod_2005_12 810 162
Prod_2005_13 8962 1402
Prod_2008_1 237 42
Prod_2008_2 271 101
Prod_2008_3 46 21
Prod_2008_4 568 166
Prod_2008_5 689 144
Prod_2008_6 1669 1330
Prod_2008_7 3190 424
Prod_2008_8 7068 1324
Prod_2008_9 17280 1543
MBUsed MBEmpty
28 14
1363 378
5031 814
2246 890
7428 1400
7359 1168
11003 2701
MBUsed MBEmpty
1321 343
11125 3246
14024 2279
21695 7653
22767 5233
MbUsed MBEmpty
92758 28960
79841 10567
46785 12432
48560 12906
8060 1943
16410 used
1064 empty
Prod:
23488 2582
Dev:
480 175
1989 236
2823 1151
1415 271
22935MBUsed 2163MBEmpty
and
17106MBUsed 2465MBEmpty
MbUsed MbEmpty
50423 7132
3544 445
339 40
2008 10.0.2766.0 (X64) 4581 901
2005 9.00.3310.00 (Intel X86) 1110 355
MBUsed MBEmpty
2282 721
7428 1128
6819 852
1085 166
645 70
1155 331
Busy OLTP Production System
5320 Used
424 Empty
Production Sharepoint DB
8452 Used
1174 Empty
Production Intranet APP DB Server
8621 Used
1068 Empty
SQL_Server_Version MBUsed MBEmpty
SQL2005 Enterprise SP3 64-bit 18212 1578
SQL2005 Enterprise SP2 64-bit 1355 108
SQL2005 Enterprise SP3 64-bit 8571 1320
SQL2005 Enterprise SP3 64-bit 2915 1428
SQL2008R2 Standard 64-bit 4478 382
SQL2005 Enterprise SP3 32-bit 610 34
SQL2008R2 Standard 64-bit 4202 360
SQL2008R2 Standard 64-bit 2884 368
SQL2005 Standard SP3 64-bit 1683 1085
SQL2005 Enterprise SP3 32-bit 5244 1230
Here’s a cross-section from servers from different walks of life:
MBUsed MBEmpty
3232 804
1124 569
5427 1497
14814 5907
47094 1970
1581 330
7370 950
10210 4065
30472 5193
Both OLTP and OLAP servers are represented, no points for guessing which is which.
Of course, now I want to know what I can do about all those gigabytes I didn’t know we’re wasting!
MBUsed MBEmpty
23472 4228
GIS Data Production Server SQL2005
MBUsed MBEmpty
612 163
Our DEV server
MBUsed MBEmpty
6232 1017
MBUsed MBEmpty
10102 1138
Server MBUsed MBEmpty
1 8255 1251
2 9792 1523
3 9078 292
MBUsed MBEmpty
47928 5718
2535 325
Rewrote as:
SELECT
COUNT (*) * 8 / 1024 AS MBUsed,
sum(cast(free_space_in_bytes as decimal)) / (1024 * 1024) AS MBEmpty
FROM sys.dm_os_buffer_descriptors;
GO
Some values:
Server Name MBUsed MBEmpty
1 147 54.978977
2 703 90.453300
3 24250 2872.929636
Prod: 26296 7357
Demo: 8831 828
DEV2 6782 193
DEV3 9770 223
DEV4 12759 5418
DEV5 1339 109
QA 6301 153
28359
1145
MBUsed MBEmpty
73 22
40 15
38 15
73 21
73 22
71 27
348 114
291 51
621 93
320 81
227 39
66 24
879 85
1258 77
168 60
331 114
544 53
1142 194
693 176
1360 80
877 79
1282 89
1001 118
2601 625
3855 922
2446 382
7052 1254
1232 67
8647 823
7096 902
3860 509
8560 1354
10617 1402
10657 2573
14334 2347
16255 2088
10094 6092
10494 4725
6801 1508
17268 1630
17894 2449
17443 2272
18271 1327
19598 944
20921 1511
23054 1089
20726 2658
41680 2688
40734 9049
MBUsed,MBEmpty
server1 211666,31883
server2 219868,32827
MBUsed MBEmpty
10682 2034
MBUsed MBEmpty
3589 535
MBUsed MBEmpty
1354 279
3422 483
28685 3623
174854 27286
9765 758
5489 1758
MBUsed MBEmpty
37655 4276
MBUsed MBEmpty
23398 5287
MBUsed MBEmpty
1231 329
MBUsed MBEmpty
5245 868
MBUsed MBEmpty
10740 2273
MBUsed MBEmpty
4200 1233
MBUsed MBEmpty
806 211
Paul,
I had to make a change because it blew up on some boxes with Arithmetic overflow error converting expression to data type int.
Below is the change
SELECT
COUNT (*) * 8 / 1024 AS MBUsed,
SUM(CONVERT(BIGINT,free_space_in_bytes)) / (1024 * 1024) AS MBEmpty
FROM sys.dm_os_buffer_descriptors;
GO
Paul , BTW I needed to use BIGINT for mine – sending you results
SELECT
COUNT (*) * 8 / 1024 AS MBUsed ,
SUM (convert(bigint,free_space_in_bytes)) / (1024 * 1024) AS MBEmpty
FROM sys.dm_os_buffer_descriptors;
GO
@Denis Cool – thanks – I’ve updated the post.
Here’s a few. I’ll try to get more later.
MBUsed MBEmpty
8099 7562 log shipping secondary
23468 4914 replica subscriber
11981 4135
109455 21227
12941 751
Quick powershell to grab the results for multiple servers (assumes a list of servers in c:tempserverlist.txt)
$SQLQuery = ‘SELECT
COUNT (*) * 8 / 1024 AS MBUsed,
SUM (CONVERT (BIGINT, free_space_in_bytes)) / (1024 * 1024) AS MBEmpty
FROM sys.dm_os_buffer_descriptors;
GO’
$servers = get-content c:tempserverlist.txt
foreach ($srv in $servers)
{
invoke-sqlcmd -Server $srv -Database master -Query $SQLQuery
}
MBUsed MBEmpty
—— ——-
719 139
287 21
2345 286
300 98
1467 972
8000 2734
317 66
1251 156
1806 58
72 21
5109 201
9608 4464
693 51
539 35
10720 2653
24090 919
569 126
10733 3633
21523 6961
6391 73
5238 2320
MBUsed MBEmpty
58 27
4 2
262 48
87 22
52 15
3128 303
5040 867
3804 70
3920 851
3920 791
4185 158
6695 626
12091 1975
8977 1727
36555 11955
57160 11188
49288 3252
5905 803
"and what you can do about it" ~paul
I’m excited, lol
MBUsed MBEmpty
1616 267
MBUsed MBEmpty
5231 525
2423 303
WssPosStorage2.uhi.amerco 4473 979
WssPosStorage3.uhi.amerco 4441 988
WssPosStorage4.uhi.amerco 4315 994
WssPosStorage1.uhi.amerco 4475 960
WssCommon.uhi.amerco 5607 1807
WssHistorical.uhi.amerco 16354 4267
All prod instances:
Host MBUsed MBEmpty
1 588 175
2 274 116
3 552 475
4 118 65
5 661 128
6 1764 229
7 53 18
8 5283 2230
9 1033 237
10 622 51
11 3138 383
12 20135 3868
13 7983 1936
14 11704 6183
15 10108 5485
16 23258 2385
17 6852 1401
18 14916 2656
19 15978 1449
20 100830 11531
21 103891 27513
22 109138 18183
23 109837 3467
24 112721 13155
MBUsed MBEmpty
68736 3153
7157 2250
23921 10200
MBUsed MBEmpty
4986 711
MBUsed MBEmpty
27406 2336
Our wasted space on 50+ instances (most of them < 8GB ram):
avg min max
41,01% 2,92% 64,97%
MBUsed MBEmpty
22864 1805
MBUsed MBEmpty
46035 4298
MBUsed MBEmpty
111129 6137
Hi Paul,
Here is a snapshot of current wasted space on my prod environment. I’m curious of the avg waste ratio.
MBUsed MBEmpty
8575 1021
16176 3680
13646 5048
18256 4650
19139 5000
15099 4293
20598 6359
20519 6373
20070 6181
20099 6226
55978 17186
20547 6338
20141 6227
84430 21028
109593 28194
38782 8310
36211 12144
Rgds,
Vincent.
MBUsed MBEmpty
387 43
29 12
1317 353
675 148
4368 196
3511 331
8606 3765 (Replication – Subscriber)
685 58
Server MBUsed MBEmpty
server1 438 58
server2 1522 253
server3 3481 434
server4 3824 157
server5 10659 2284
server6 11601 3135
server7 13290 3109
Server MBUsed MBEmpty
DW 56112 6012
Report 49768 1834
Hello Paul,
MBUsed: 10637
MBEmpty: 1465
-Klaus
MBUsed MBEmpty
23747 3819
MBUsed – 96398
MBEmpty – 11451
Production systems:
MBUsed MBEmpty
861 320
19220 2728
13942 403
MBUsed MBEmpty
196288 120675
MBUsed MBEmpty
6588 1127
Prod
MBUsed MBEmpty
3609 145
354 66
1611 337
3271 561
1226 208
Prod Instances
Used Empty
111267 30389
23994 4159
23852 5267
14302 1702
11958 1877
2994 253
1001 133
669 88
592 131
252 80
Looking forward to seeing what to do about it.
MB Used – 23615
MB Empty – 6442
1. 1448 / 392
2. 11984 / 3335
3. 4975 / 1063
4. 12605 / 1998
MBUsed MBEmpty
1666 1076
32003 3026
10466 1898
22485 5930
Name:Used:Empty
Prod1:5239:1764
Prod2:3082:602
Dev1:3699:732
Rep1:4080:2670
Bak1:4095:3846
Tst1:2847:2660
MBUsed MBEmpty
52075 15392
MBUsed | MBEmpty
3 | 1
9 | 2
12 | 3
38 | 16
46 | 16
49 | 15
50 | 18
52 | 21
55 | 21
59 | 20
60 | 24
66 | 10
67 | 25
225 | 74
254 | 70
383 | 81
488 | 104
512 | 58
514 | 66
602 | 274
635 | 89
674 | 133
778 | 81
834 | 85
870 | 162
888 | 91
960 | 144
1302 | 52
1490 | 260
1558 | 64
1667 | 292
2405 | 2188
2424 | 343
2504 | 615
2789 | 137
5039 | 822
5184 | 876
5317 | 327
5363 | 1628
38157 | 5525
56141 | 6550
67323 | 17222
MBUsed MBEmpty
5731 743
Our production servers (2005, 2008, 2008 R2):
MBUsed MBEmpty
219 46
20 7
61 18
429 60
563 291
234 53
617 185
293 92
683 33
401 92
350 130
619 237
2357 418
985 638
1569 225
5776 1391
564 38
6325 312
2870 283
3861 253
1390 75
4917 1065
124 12
5067 1155
5817 882
6023 610
2463 333
1940 357
20809 7663
23834 924
25388 4831
23657 6663
23718 7719
482 175
270 102
10050 2340
16012 1629
10553 3067
50990 3079
MBUsed MBEmpty
12356 1236
15806 1214
MBUsed MBEmpty
9534 2446
628 188
630 188
152 58
A few of my Production servers:
MBUsed MBEmpty
1574 97
20981 3799
16017 2054
6931 1503
110899 16880
MBUsed MBEmpty
50116 5113
159801 26334
89519 9963
51383 5540
3114 791
10696 2889
12320 3861
14876 997
38 11
858 95
8331 1208
5941 4128
some of our production servers
2005 ent/std
x32
9838 1117
x64
26796 1678
2494 224
753 33
MBUsed MBEmpty
58090 13799
On a server that’s mostly used for scheduled jobs/automated data processing
Used Free
8698 1822
16GB memory on server, max_memory set to 12.
Used Empty
24061 7499
8452 442
Mbused MBEMPTY
35488 1792
MbUsed MbEmpty
455 63
1088 210
7196 1434
182 31
330 40
518 108
140 22
925 151
1698 273
2105 363
74 13
1265 147
896 170
679 221
420 46
921 490
298 113
112 33
816 228
137 16
2192 88
2 0
321 70
701 20
607 114
2663 238
1609 252
2602 505
6861 682
128 30
3257 658
394 77
298 80
2450 456
2057 245
Production ERP DB and DataWarehouse
MBUsed MBEmpty
17411 1292
MBUsed MBEmpty
8055 529
Testing, development
MBUsed MBEmpty
1784 234
Used Empty
132 30
1580 238
2449 113
4393 218
24703 2668
17589 1277
21072 2107
14536 1496
17647 4352
3774 1331
30406 2719
For our main production server
Used Empty
209345 20222
108187 14766
MBUsed MBEmpty
———– ——————–
3334 257
Prod SQL 2008 R2:
MBUsed MBEmpty
55048 2466
Prod SQL 2005:
MBUsed MBEmpty
47783 4239
Hyper-V
DEV 527 | 118 [2005/32bit]
DEV 527 | 118 [2005/64bit]
DEV 913 | 53 [2008/64bit]
DEV 5 | 2 [2008R2/64bit]
Physical
PROD 7801 | 1417 [2005/32bit]
PROD 643 | 82 [2005/64bit]
PROD 4608 | 311 [2008/64bit
Physical
Production 2005 SP3 32bit: 25325 MBUsed | 2129 MBEmpty
Production 2005 SP3 32bit: 5879 MBUsed | 412 MBEmpty
VMWare
Production 2005 SP3 32bit: 1496 MBUsed | 110 MBEmpty
I’m not sure what the numbers mean, but the fact that servers D and A should in theory be processing almost the same amount of data, with the same pattern, makes me wonder why A uses 4x as much memory. The primary difference is with merge replication, D is 90% publisher and A is 90% subscriber, but only replicating on about 1GB of data. In total they store several hundred GB.
Looking forward to your analysis.
Server Used Empty Replication
—–
(System mostly idle or under load – similar values)
D 4086 817 Publisher
A 17165 3969 Subscriber
Used\Empty
OLTP: 31107 7425
Reporting: 30835 4086
MBUsed MBEmpty
110786 20769
6718 607
Used Empty
4620 1396
Looking forward to see the results.
SRV MBUsed MBEmpty
P1 11157 2035
P2 ? ?
P3 6384 1837
D1 26 9
D2 859 362
D3 8 3
MBUsed MBEmpty
15437 2247