Nested loops have their place in development, but if you aren't careful, they can lead to serious performance degradation due to the fact that the inner loop will run a certain number of times, multiplied by the number of times the outer loop runs.
It is often possible to avoid having to run a nested loop, in favor of running two separate loops (which means that each loop would only run a set number of times).
Consider the following code:
var innerGR;
var results = [];
var outerGR = new GlideRecord('table_name');
outerGR.query();
while (outerGR.next()) {
innerGR = new GlideRecord('other_table_name');
innerGR.addQuery('field', outerGR.getValue('something_to_compare'));
innerGR.query();
while (innerGR.next()) {
results.push(innerGR.getValue('some_field'));
}
}
This code requires constructing a new GlideRecord object (innerGR), a new query, and iterating over each record - for every record found within outerGR. The only reason it's constructed this way, is because we want to get a value from records in innerGR that meet a query based on another value from outerGR, and push them into results. However, we can accomplish this much more efficiently by simply separating out these two queries, and creating a temporary array to store up the values from outerGR, that we're using in the query in innerGR like so:
var queryValues = [];
var results = [];
var outerGR = new GlideRecord('table_name');
outerGR.query();
while (outerGR.next()) {
queryValues.push(outerGR.getValue('something_to_compare'));
}
innerGR = new GlideRecord('other_table_name');
innerGR.addQuery('field', 'IN', queryValues);
innerGR.query();
while (innerGR.next()) {
results.push(innerGR.getValue('some_field'));
}
As you can see, by pushing the values we want to search on into an array, and then performing only one outer (though no longer outer, but stand-alone) query, we can dramatically improve performance of our script.