In order to evaluate expressions faster, Appian automatically evaluates queries in parallel. This means that instead of waiting for each query to evaluate one after another, independent queries will be evaluated at the same time if there are additional resources available, reducing the overall time it takes to evaluate the expression. This includes database queries, web service calls, custom plug-ins, and even Appian functions that query data stored within Appian.
Queries are evaluated in parallel in any place where there's no way for one part of the expression to affect another part, such as:
Of course, any parts of the expression that depend on a query will only be evaluated after that query is complete, thus ensuring that the result will be the same regardless of whether the expression is evaluated serially or in parallel. You may see this reflected in the Performance tab results for a particular interface.
Let's look an example to illustrate how it would be evaluated in parallel.
Say you want to get the list of all account managers who don't currently have an active customer account. You may use an expression like the following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
a!localVariables(
local!customers: {
rule!getAllDomesticCustomers(),
rule!getAllInternationalCustomers()
},
local!accountManagers: rule!getAccountManagersByRegionAndVertical(
regions: rule!getAllRegions(),
verticals: rule!getAllVerticals()
),
local!AMsWithoutAccounts: difference(local!accountManagers, local!customers.manager),
a!forEach(
items: local!AMsWithoutAccounts,
expression: rule!displayUserName(fv!item)
)
)
where rule!displayUserName
calls the user
function, which is considered a query because it retrieves user information from Appian. When every part of this expression is evaluated serially, it looks something like this:
However, when there are resources available to evaluate queries in parallel, the evaluation would look like this:
Where:
local!customers
and local!allAccountManagers
evaluate in parallel because independent local variables are evaluated in parallel when they contain a query.rule!getAllDomesticCustomers
and rule!getAllInternationalCustomers
evaluate in parallel because they are separate items in a list and both are queries.local!AMsWithoutAccounts
is not evaluated in parallel because it depends on both local!customers
and local!allAccountManagers
.a!forEach
iterations evaluate in parallel after evaluating local!AMsWithoutAccounts
because rule!displayUserName
calls the user
function, which is considered a query.All of this happens without making any changes to the overall expression; Appian can automatically detect which parts of the expression are independent and evaluate them in parallel to decrease the overall evaluation time.
If you look at the Performance tab for this expression, you may identify rule!getAllInternationalCustomers
and rule!getAllDomesticCustomers
as bottlenecks and target them for performance improvements.
If you were able to improve the performance of rule!getAllDomesticCustomers
to 100 ms, you would notice that the overall evaluation time would not decrease because that query is being evaluated in parallel with other queries which are still taking longer.
However, if you instead were to improve the performance of rule!getAllInternationalCustomers
to 100 ms, the overall evaluation time would decrease by 100 ms instead of 400 ms because it is still evaluating in parallel with local!accountManagers
, which now becomes the new bottleneck.
Parallel Evaluation of Expressions