Calculating detailed class/table size
In the good old days (tm) determining the size of the data, streams, and indices for a class/table was easy - you just ran %GSIZE and check D, S, and I globals respectively.
However, nowadays sharding, optimized global names, and indices in separate globals produce %GSIZE output looking like this:
Global Size Display of /irissys/data/IRIS/mgr/irisshard/
1:35 PM Dec 02 2020
IRIS.Msg 1 IRIS.MsgNames 1 IRIS.SM.Shard 1
IS.DGoWeK.1 24359 IS.DGoWeK.2 3 IS.DGoWeK.3 2810
IS.DGoWeK.4 2542 IS.V0Zli.1 373 IS.V0Zli.2 2
IS.k22Ht.1 238028 IS.k22Ht.2 3 IS.k22Ht.3 25819
IS.k22Ht.4 7426 ISC.Src.Jrn 1 ROUTINE 1
oddBIND 1 oddCOM 1 oddDEF 1
oddDEP 1 oddEXT 1 oddEXTR 1
oddMAP 1 oddMETA 1 oddPKG 1
oddPROC 1 oddPROJECT 1 oddSQL 1
oddStudioDocument 1 oddStudioMenu 1 oddTSQL 1
oddXML 1 rBACKUP 1 rINC 1
rINCSAVE 1 rINDEX 1 rINDEXCLASS 1
rINDEXEXT 7 rINDEXSQL 1 rMAC 1
rMACSAVE 1 rMAP 1 rOBJ 1
TOTAL: 301403Sure, you can follow the storage definitions and decode this to understand where your space has gone but it's not obvious anymore.
Enter ClassSize query a custom tvf showing you globals related to classes, their size, and function.
Call it with two arguments:
- package - where to search for persistent classes
- fast - if true returns only allocated space
Here's what it looks like on a combination of sharded and non-sharded classes:
.png)
The limitation is - currently, only the info about the current shard is returned for sharded classes.
Comments
nice work!!!
Thank you for this - excellent, keep them coming !!!
When I click on "ClassSize query" I am getting a 404 error. Can this link be updated so I can duplicate this?
Thanks. Updated the post.
For small globals where MB is too coarse a unit of measurement, do you think it would be worthwhile to calculate the size of a global based on the number of blocks allocated for it, then multiply that number by the blocksize?
For example,
Do ##class(%GlobalEdit).GetGlobalSizeBySubscript(globalDirectory, globalName, "", .size)
set numBlocks = Size("Blocks","Total")
set blockSizeForDB = ##class(%GlobalEdit).Open(globalName, globalDirectory).DatabaseBlockSize
set globalSize = numBlocks * blockSizeForDB
write "Size for global """, globalName, """ in kilobytes: ", globalSize, !When I developed this query I was concerned with large globals, certainly if there's an interest in small globals' size this might come useful.