{"id":3681,"date":"2021-11-09T19:43:58","date_gmt":"2021-11-10T03:43:58","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/cosmosdb\/?p=3681"},"modified":"2021-11-24T07:14:16","modified_gmt":"2021-11-24T15:14:16","slug":"improve-application-performance-with-java-v4-sdk-for-cosmos-db","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cosmosdb\/improve-application-performance-with-java-v4-sdk-for-cosmos-db\/","title":{"rendered":"Improve application performance with Java SDK v4 for Azure Cosmos DB"},"content":{"rendered":"<p><span style=\"color: #000000;\">The <a href=\"https:\/\/docs.microsoft.com\/azure\/cosmos-db\/sql\/sql-api-sdk-java-v4\" target=\"_blank\" rel=\"noopener\">Java SDK v4 for Azure Cosmos DB<\/a> has many improvements and new APIs to help increase the performance of your applications. In this blog post, I will highlight a few of these improvements that help improve application performance by reducing the number of network roundtrips and latency when using direct mode in the Java v4 SDK.<\/span><\/p>\n<p><span class=\"TextRun SCXW123123058 BCX8\" lang=\"EN-US\" style=\"color: #000000;\" xml:lang=\"EN-US\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW123123058 BCX8\" data-ccp-parastyle=\"No Spacing\">Here is\u00a0<\/span><span class=\"NormalTextRun SCXW123123058 BCX8\" data-ccp-parastyle=\"No Spacing\">what\u00a0<\/span><span class=\"NormalTextRun SCXW123123058 BCX8\" data-ccp-parastyle=\"No Spacing\">the SDK does behind the scenes\u00a0<\/span><span class=\"NormalTextRun SCXW123123058 BCX8\" data-ccp-parastyle=\"No Spacing\">for a\u00a0<\/span><span class=\"NormalTextRun SCXW123123058 BCX8\" data-ccp-parastyle=\"No Spacing\">query:<\/span><\/span><\/p>\n<p style=\"padding-left: 40px;\"><a href=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2021\/11\/QueryPlan.png\"><img decoding=\"async\" class=\"alignnone wp-image-3739\" src=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2021\/11\/QueryPlan-300x198.png\" alt=\"Image QueryPlan\" width=\"605\" height=\"399\" srcset=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2021\/11\/QueryPlan-300x198.png 300w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2021\/11\/QueryPlan-768x507.png 768w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2021\/11\/QueryPlan.png 819w\" sizes=\"(max-width: 605px) 100vw, 605px\" \/><\/a><\/p>\n<figure id=\"attachment_3721\" class=\"wp-caption alignnone\" aria-describedby=\"caption-attachment-3721\"><figcaption id=\"caption-attachment-3721\" class=\"wp-caption-text x-hidden-focus\">Image: How the SDK handles queries<\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\">In\u00a0<a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/cosmos-db\/sql\/performance-tips-java-sdk-v4-sql?tabs=api-async%22%20%5Cl%20%22networking\" target=\"_blank\" rel=\"noopener\">direct mode<\/a>, every time a query is executed via the SDK the first step is a network call to retrieve the query plan before the query can be executed on the replicas. Query plan, which is used internally, has the execution information required to execute a query on the replicas. This query plan retrieval adds overhead for every query. With the Java SDK you now have options to either minimize the query plan calls or eliminate them. Let us look at the options.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-size: 14pt; color: #000000;\"><strong>Query plan caching<\/strong><\/span><\/p>\n<p><span style=\"color: #000000;\">The query plan, for a query scoped to a single partition, is cached on the client. This eliminates the need to make a call to the gateway to retrieve the query plan after the first call. The key for the cached query plan is the SQL query string. You need to make sure the query is parametrized. If not, the query plan cache lookup will often be a cache miss as the query string is unlikely to be identical across calls. Query plan caching is enabled by default for version 4.20.0 or above. Let us look at a couple of query strings to better understand the concept.<\/span><\/p>\n<pre class=\"prettyprint\">SELECT * FROM o WHERE o.category = @category and o.author= @author<\/pre>\n<p><span style=\"color: #000000;\">Once cached, the query plan look-up for the above query string will be a cache hit irrespective of the actual parameter (@category and @author) values.<\/span><\/p>\n<pre class=\"prettyprint\">SELECT * FROM o WHERE o.category =\u201cDatabases\u201d and o.author= \u201cRavi\u201d<\/pre>\n<p><span style=\"color: #000000;\">Once cached, the query plan look-up for the above query string will be a cache hit, only for a query string with parameter values \u201cDatabase\u201d and \u201cRavi\u201d, because the query is not parameterized.<\/span><\/p>\n<p><span style=\"color: #000000;\">\u201ccategory\u201d is the partition key for both the queries. As I have mentioned previously, query caching only works for queries scoped to a single partition. The partition key value must be set using \u201cCosmosQueryRequestOptions\u201d object for query plan caching to work.\u00a0<\/span><\/p>\n<p><span style=\"color: #000000;\">Every time there is a cache hit for a query plan you will see the following message in the logs.<\/span><\/p>\n<pre class=\"prettyprint\">\u201cSkipping query plan round trip by using the cached plan\u201d<\/pre>\n<p><span style=\"color: #000000;\">Query plan caching currently works for queries with filters. This feature can also be leveraged from the Spring connector when using method derived queries. Currently, queries defined with \u201c@Query\u201d spring data annotation, do not take advantage of Query plan caching.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-size: 14pt; color: #000000;\"><b>CosmosAsyncContainer#readAllItems<\/b>\u00a0<\/span><\/p>\n<p><span style=\"color: #000000;\">This API allows you to retrieve all documents with the same partition key value. Behind the scenes, the SDK generates and executes a query on the replicas, but there will be no call made to the gateway for query plan. This API is available from SDK version 4.15.0 or above.\u00a0<\/span><\/p>\n<pre class=\"prettyprint\">container.readAllItems(new PartitionKey(category), cosmosItemRequestOptions, Book.class)\r\n\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><span style=\"font-size: 14pt; color: #000000;\"><strong>CosmosAsyncContainer#readMany<\/strong><\/span><\/p>\n<p><span style=\"color: #000000;\">The ReadMany API does something similar for retrieving multiple documents by ID and partition Key. Simply put, if you want to retrieve multiple documents by ID and partition key, instead of calling &#8220;CosmosAsyncContainer#readItem&#8221; point read API, multiple times you can use this API to retrieve all the documents in parallel. Once again, the SDK behind the scenes will generate and execute the query on the replicas without making a call to the gateway for query plan. This API is available from SDK version 4.5.0 or above.<\/span><\/p>\n<pre class=\"prettyprint\">CosmosItemIdentity itemIdentity1 = new CosmosItemIdentity(new PartitionKey(\"Programming Languages\"), \"4\");\r\nCosmosItemIdentity itemIdentity2 = new CosmosItemIdentity(new PartitionKey(\"Databases\"), \"6\");\r\nList&lt;CosmosItemIdentity&gt; itemIdentities = Lists.newArrayList(itemIdentity1,itemIdentity2);\r\ncontainer.readMany(itemIdentities,Book.class);<\/pre>\n<p><span style=\"color: #000000;\">As always, we highly recommend upgrading to the latest version of the SDK for best results.<\/span><\/p>\n<p><span style=\"color: #000000;\"><strong>Next Steps:<\/strong><\/span><\/p>\n<ul>\n<li><a href=\"https:\/\/docs.microsoft.com\/azure\/cosmos-db\/sql\/sql-api-sdk-java-v4\" target=\"_blank\" rel=\"noopener\">Azure Cosmos DB Java SDK v4 technical documentation<\/a><\/li>\n<li><a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/cosmos-db\/sql\/sql-api-java-sdk-samples\" target=\"_blank\" rel=\"noopener\">Java SDK v4 getting started sample application<\/a><\/li>\n<li><a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/cosmos-db\/sql\/sql-api-sdk-java-v4\">Release notes and additional resources <\/a><\/li>\n<\/ul>\n<p><span style=\"color: #000000;\">Do you have feedback about the Java SDK for Azure Cosmos DB? Share feedback directly with the Azure Cosmos DB engineering team via GitHub issues at<\/span>\u00a0<a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-java\/issues\">azure-sdk-for-java.<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Java SDK v4 for Azure Cosmos DB has many improvements and new APIs to help increase the performance of your applications. Discover how the new version helps improve application performance by reducing the number of network roundtrips and latency when using direct mode in the Java SDK v4.<\/p>\n","protected":false},"author":75510,"featured_media":61,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[14,643],"tags":[],"class_list":["post-3681","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-core-sql-api","category-java-sdk"],"acf":[],"blog_post_summary":"<p>The Java SDK v4 for Azure Cosmos DB has many improvements and new APIs to help increase the performance of your applications. Discover how the new version helps improve application performance by reducing the number of network roundtrips and latency when using direct mode in the Java SDK v4.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts\/3681","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/users\/75510"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/comments?post=3681"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts\/3681\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/media\/61"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/media?parent=3681"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/categories?post=3681"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/tags?post=3681"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}