marklogicmarklogic-9

MarkLogic - Performance variation in custom rest GET REST service


MarkLogic version 9.0-6.2

I have a custom rest GET service that takes an ID (lets say PolicyId) and returns a document (only 1 document returned always). Element Range index is created on PolicyId. I have 100 different documents, one for each PolicyId.

When I call the service through SoapUI tool the first time with a PolicyId, I see a response time of around 2 sec, but from the second call onward (even if I try with a different PolicyId), I see a response time of around 30 milliseconds.

Now, if I close SoapUI tool and retry the above steps after 1 hour, again I see a response time of 2 sec for the first call.

I am trying to understand the behavior and its relation to caching in MarkLogic. Why am I getting slower response the first time? How am I getting faster response from second time onward even if I give a different PolicyId? Is there a way we can improve the performance for the very first call itself? Any suggestion on better performance tools for REST APIs?

Any inputs are highly appreciated.


Solution

  • You mentioned that you have an element range index on PolicyId. Element range indexes are very fast because they are in-memory indexes. If that index isn't already in memory, then the entire index needs to be loaded into memory before it can be used. Your first query is likely triggering the load of the index (which takes time), while subsequent requests are benefitting from it already being loaded. After some period of not using the index, it may be swapped out in favor of other memory consumers.

    Is there a way we can improve the performance for the very first call itself?

    Based on your description, I think you're doing something like this:

      fn.head(cts.search(cts.jsonPropertyRangeQuery("PolicyId", "=", policyId)))
    

    For this kind of query, you don't necessarily need a range index -- you're not dealing with an inequality or a type-sensitive query. I'd do a performance test using the Universal Index instead.

      fn.head(cts.search(cts.jsonPropertyValueQuery("PolicyId", policyId)))
    

    I'd expect that result to come back between your 2 seconds and 30 milliseconds, but likely with less variation.