Evgeny Shvarov · Nov 30, 2017

Index Globals: Take Away or Rebuild?

Hi, Community!

Consider you move data from one server to another or make a deployment with persistent data. What do you do with index globals?

Is it always better to rebuild them or there are some cases when it worth to take them too?

1 587
Discussion (7)2
Log in or sign up to continue

I've rarely rebuilt indexes while moving Cache DBs. It's a complex added step that is probably not worth doing unless you have very large DB or limited copy throughput.

Tom Fitzgibbon gototomAtG...l

Agree with Robert (how couldn't I? ;) )

The crucial questions is how long does it take to copy the index vs. rebuilding it? And, if your index has not been rebuilt for a long time, will a reorganized global be beneficial to your performance? It usually is.

Also note that the recent versions of %BuildIndices() exploit multiple cores whenever possible and will run much faster than the older, serialized approach.

As Eduard mentioned, functional indices, or indices on collection with handcrafted BuildValueArray() for that matter, may be a different beast and may run for a long time. 

It's a rare case in combination with %Persistent,
but it makes sense also to exclude any class with Property Abstract=1 in your Query

Would skip classes with  several levels of inheritance from %Persistent. Use SubclassOf query instead.

Complex functional indices which take a long time to build my be worth moving, otherwise - no.

Rebuild takes time -  ONCE
and gives you the unique chance to fill the created index in contiguous global content blocks.
That pays back at ever access by less global pointer blocks whatever storage technology you use.

Thanks for the answers!

The combined answer is - build it again if you don't care about the time during deployment.

For Caché persistent classes I like this snippet from [@Kyle.Baxter] which rebuilds all persistent classes' indexes in a Namespace:

s sql="select Name from %Dictionary.CompiledClass where system=0 and NOT(Name %Startswith '%') AND SUPER [ 'Persistent'"

s rs=##class(%SQL.Statement).%ExecDirect(,sql)

while rs.%Next() { s sc= $classmethod(rs.%GetData(1),"%BuildIndices") w "Built "_rs.%GetData(1)_" with return code = "_sc,! }