· Dec 2, 2020 2m read

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:  301403

Sure, 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:

The limitation is - currently, only the info about the current shard is returned for sharded classes.

Discussion (6)3
Log in or sign up to continue

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, !