Now it is obvious that ^realglobal has 11.3 times the size of ^testglobal
while your ^testglobal seems to have all blocks in buffers in memory
this is rather unlikely for ^realglobal.
So repeated reloading of blocks from disk seems to cause the delay
If you have the chance to double or triple your global buffers
you most likely may see improved processing of your $O()

Follow up to @Dmitry Maslennikov:
Error on IRIS side:  ACCESS DENIED  ODBC can't connect ===> timeout
Why  ACCESS DENIED ? 
The most likely cause

  • you run multiple ODBC connections in parallel
  • you use the same fixed USER for access to IRIS
  • maximum license slots by user is ~25
  • once you pass the limit your 25 slots get converted to 25 single licenses
  • any further connection consumes a full license 
  • until you run out of available licenses ==> ACCESS DENIED
  • you can get out of that trap only if ALL connections of that user are closed 

You can avoid this by

  • limiting your ODBC connections below 24
  • or run your ODBC access in  serial mode
  • or use multiple users for access with limit <24

Hi @Vivian Lee !
I think you had no chance to see the problem in docs
You mentioned 
a custom class that extends %Text.English
this might be the cause of your problem.
The class is not visible in normal class reference (don't ask me why) 

Default %Text.English has a Parameter  NOISEWORDS100 =
"the of and a to in is you that it he for was on are as with his they at be this from I have or by one had not but what all were when we there can an your which their said if do will each about how up out them then she many some so these would other into has more her two like him see time could no make than first been its who now my made over did down only way find use may long little very after called just where most know get through back";

So you might be affected by these NOISEWORDS.
I failed to find any useful public documentation on this parameter and also %Text.Text is not too useful