{"id":4422,"date":"2022-06-21T13:54:41","date_gmt":"2022-06-21T20:54:41","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/cosmosdb\/?p=4422"},"modified":"2022-06-21T13:54:41","modified_gmt":"2022-06-21T20:54:41","slug":"introducing-a-new-system-function-and-optimized-query-operators","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cosmosdb\/introducing-a-new-system-function-and-optimized-query-operators\/","title":{"rendered":"Introducing a new system function and optimized query operators"},"content":{"rendered":"<p><span data-contrast=\"auto\">The query engine in <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/cosmos-db\/sql\/sql-query-getting-started\">Azure Cosmos DB Core (SQL) API<\/a> now has a new system function and optimizations for a set of query operations to better use the index. In this post we\u2019ll cover the new DateTimeBin function as well as improvements to GROUP BY, DISTINCT, OFFSET LIMIT, and JOIN.<\/span><\/p>\n<p><span data-contrast=\"auto\">These example scenarios are for Contoso, a fictional online retailer that stores a product catalog of 1 million items in Azure Cosmos DB. They have 1.5 GB of data stored in a container partitioned by the id property. Here\u2019s an example document:<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<blockquote>\n<pre class=\"prettyprint\">{ \r\n    \"id\":\u202f\"4e487804-a9a8-463c-b767-5fe307a86c47\",\r\n    \"Name\":\u202f\"Embroidered\u202fSilk\u202fShirt\", \r\n    \"Price\":\u202f35.0, \r\n    \"Category\":\u202f\"Clothing\", \r\n    \"Description\":\u202f\"Luxurious silk shirt with hand embroidered flowers.\",\r\n    \"FirstAvailable\":\u202f\"2021-06-21T00:00:00.0000000Z\",\r\n    \"CustomerRatings\":\u202f[ \r\n        { \r\n            \"Username\":\u202f\"User1\", \r\n            \"Stars\":\u202f5 \r\n        }, \r\n        { \r\n            \"Username\":\u202f\"User2\", \r\n            \"Stars\":\u202f4 \r\n        }, \r\n        { \r\n            \"Username\":\u202f\"User3\", \r\n            \"Stars\":\u202f5 \r\n        } \r\n    ] \r\n}\r\n\r\n<\/pre>\n<\/blockquote>\n<h3><span class=\"TextRun SCXW177550168 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"none\"><span class=\"NormalTextRun SpellingErrorV2Themed SCXW177550168 BCX8\" data-ccp-parastyle=\"heading 2\">DateTimeBin<\/span> <span class=\"NormalTextRun SCXW177550168 BCX8\" data-ccp-parastyle=\"heading 2\">s<\/span><span class=\"NormalTextRun SCXW177550168 BCX8\" data-ccp-parastyle=\"heading 2\">ystem <\/span><span class=\"NormalTextRun SCXW177550168 BCX8\" data-ccp-parastyle=\"heading 2\">f<\/span><span class=\"NormalTextRun SCXW177550168 BCX8\" data-ccp-parastyle=\"heading 2\">unction<\/span><\/span><span class=\"EOP SCXW177550168 BCX8\" data-ccp-props=\"{&quot;335559738&quot;:40,&quot;335559739&quot;:0}\">\u00a0<\/span><\/h3>\n<p><span data-contrast=\"auto\">Contoso wants to know how many products were made available each week in June so far. They can use DateTimeBin, a new system function that makes aggregation queries with dates even more useful for analyzing data.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">Contoso wrote the query below to achieve this:<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<pre class=\"prettyprint\">SELECT\u202fCount(1)\u202fas\u202fNewProduts,\u202fDateTimeBin(c.FirstAvailable,\u202f'd',\u202f7)\u202fAS\u202fDayAvailable \r\nFROM\u202fc \r\nWHERE\u202fc.FirstAvailable\u202f&gt;\u202f\"2022-06-01T00:00:00.0000000Z\" \r\nGROUP\u202fBY\u202fDateTimeBin(c.FirstAvailable,\u202f'd',\u202f7)\r\n\r\n<\/pre>\n<p><span class=\"TextRun SCXW207847793 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW207847793 BCX8\">When using the <\/span><span class=\"NormalTextRun SpellingErrorV2Themed SCXW207847793 BCX8\">DateTimeBin<\/span><span class=\"NormalTextRun SCXW207847793 BCX8\"> function,<\/span><span class=\"NormalTextRun SCXW207847793 BCX8\"> specify a<\/span><span class=\"NormalTextRun SCXW207847793 BCX8\"> UTC<\/span> <span class=\"NormalTextRun SpellingErrorV2Themed SCXW207847793 BCX8\">DateTime<\/span><span class=\"NormalTextRun SCXW207847793 BCX8\"> string in the<\/span> <span class=\"NormalTextRun SCXW207847793 BCX8\">format `<\/span><span class=\"NormalTextRun SpellingErrorV2Themed SCXW207847793 BCX8\">YYYY-MM<\/span><span class=\"NormalTextRun SpellingErrorV2Themed SCXW207847793 BCX8\">-DDThh:mm:ss<\/span><span class=\"NormalTextRun SCXW207847793 BCX8\">. <\/span><span class=\"NormalTextRun SpellingErrorV2Themed SCXW207847793 BCX8\">fffffffZ<\/span><span class=\"NormalTextRun SCXW207847793 BCX8\">`<\/span><span class=\"NormalTextRun SCXW207847793 BCX8\">,<\/span><span class=\"NormalTextRun SCXW207847793 BCX8\"> a <\/span><span class=\"NormalTextRun SCXW207847793 BCX8\">unit of measurement to bin by<\/span><span class=\"NormalTextRun SCXW207847793 BCX8\">, and optionally <\/span><span class=\"NormalTextRun SCXW207847793 BCX8\">the size of the bins<\/span><span class=\"NormalTextRun SCXW207847793 BCX8\">. A full list of supported <\/span><span class=\"NormalTextRun SCXW207847793 BCX8\">parameters<\/span><span class=\"NormalTextRun SCXW207847793 BCX8\"> can be found in <\/span><span class=\"NormalTextRun SCXW207847793 BCX8\">the<\/span> <\/span><a class=\"Hyperlink SCXW207847793 BCX8\" href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/cosmos-db\/sql\/sql-query-datetimebin\" target=\"_blank\" rel=\"noreferrer noopener\"><span class=\"TrackChangeTextInsertion TrackedChange SCXW207847793 BCX8\"><span class=\"FieldRange SCXW207847793 BCX8\"><span class=\"TextRun Underlined SCXW207847793 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"none\"><span class=\"NormalTextRun CommentStart CommentHighlightPipeRest CommentHighlightRest SCXW207847793 BCX8\" data-ccp-charstyle=\"Hyperlink\">documentation<\/span><\/span><\/span><\/span><\/a><span class=\"TextRun SCXW207847793 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"auto\"><span class=\"NormalTextRun CommentHighlightPipeRest SCXW207847793 BCX8\">.<\/span><\/span><span class=\"EOP SCXW207847793 BCX8\" data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<p>&nbsp;<\/p>\n<h3>GROUP BY and DISTINCT optimizations<\/h3>\n<p><span class=\"TextRun SCXW207625288 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW207625288 BCX8\">Contoso can also take advantage of <\/span><span class=\"NormalTextRun SCXW207625288 BCX8\">new improvements to <\/span><span class=\"NormalTextRun SCXW207625288 BCX8\">GROUP BY and DISTINCT<\/span><span class=\"NormalTextRun SCXW207625288 BCX8\"> that allow <\/span><span class=\"NormalTextRun SCXW207625288 BCX8\">the<\/span><span class=\"NormalTextRun SCXW207625288 BCX8\">m<\/span><span class=\"NormalTextRun SCXW207625288 BCX8\"> to <\/span><span class=\"NormalTextRun SCXW207625288 BCX8\">better utilize<\/span><span class=\"NormalTextRun SCXW207625288 BCX8\"> the index.<\/span><span class=\"NormalTextRun SCXW207625288 BCX8\"> Previously, <\/span><span class=\"NormalTextRun SCXW207625288 BCX8\">queries with these operators would use the index while evaluating <\/span><span class=\"NormalTextRun SCXW207625288 BCX8\">filters, but not for evaluating the operator itself.<\/span><span class=\"NormalTextRun SCXW207625288 BCX8\"> With these new improvements these operators <\/span><span class=\"NormalTextRun SCXW207625288 BCX8\">can also<\/span> <span class=\"NormalTextRun SCXW207625288 BCX8\">benefit from <\/span><span class=\"NormalTextRun SCXW207625288 BCX8\">either single or composite<\/span> <span class=\"NormalTextRun SCXW207625288 BCX8\">indices<\/span><span class=\"NormalTextRun SCXW207625288 BCX8\">, leading to both increased performance and reduced <\/span><span class=\"NormalTextRun SpellingErrorV2Themed SCXW207625288 BCX8\">RU<\/span><span class=\"NormalTextRun SpellingErrorV2Themed SCXW207625288 BCX8\">s<\/span><span class=\"NormalTextRun SpellingErrorV2Themed SCXW207625288 BCX8\">.<\/span><\/span><span class=\"EOP SCXW207625288 BCX8\" data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<p>&nbsp;<\/p>\n<h4>GROUP BY<\/h4>\n<p><span class=\"TextRun SCXW67547011 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW67547011 BCX8\" data-ccp-parastyle=\"heading 3\">In the query below, Contoso is using GROUP BY to get <\/span><span class=\"NormalTextRun SCXW67547011 BCX8\" data-ccp-parastyle=\"heading 3\">the <\/span><span class=\"NormalTextRun SCXW67547011 BCX8\" data-ccp-parastyle=\"heading 3\">average price<\/span><span class=\"NormalTextRun SCXW67547011 BCX8\" data-ccp-parastyle=\"heading 3\"> of products in each category<\/span><span class=\"NormalTextRun SCXW67547011 BCX8\" data-ccp-parastyle=\"heading 3\">.<\/span><span class=\"NormalTextRun SCXW67547011 BCX8\" data-ccp-parastyle=\"heading 3\"> Because there is an aggregation on Price in addition to grouping by<\/span> <span class=\"NormalTextRun SCXW67547011 BCX8\" data-ccp-parastyle=\"heading 3\">Category, <\/span><span class=\"NormalTextRun SCXW67547011 BCX8\" data-ccp-parastyle=\"heading 3\">this query would benefit from a composite index on those two properties.<\/span><span class=\"NormalTextRun SCXW67547011 BCX8\" data-ccp-parastyle=\"heading 3\"> If there were filter properties outside of the aggregation or grouping, a single index on those properties would <\/span><span class=\"NormalTextRun SCXW67547011 BCX8\" data-ccp-parastyle=\"heading 3\">also be evaluated.<\/span><\/span><span class=\"EOP SCXW67547011 BCX8\" data-ccp-props=\"{&quot;335559738&quot;:40,&quot;335559739&quot;:240}\">\u00a0<\/span><\/p>\n<pre class=\"prettyprint\">SELECT\u202fAVG(c.Price),\u202fc.Category\u202f \r\nFROM\u202fc\u202f \r\nGROUP\u202fBY\u202fc.Category<\/pre>\n<p><span data-contrast=\"auto\"><em>Previous query charge:<\/em> 23,885.49 RUs<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span data-contrast=\"auto\"><em>Previous execution time:<\/em> 30.72 seconds<\/span><span data-ccp-props=\"{&quot;335559739&quot;:0}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\"><em>New query charge:<\/em> 371.51 RUs<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span data-contrast=\"auto\"><em>New execution time:<\/em> 6.35 seconds<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<p>&nbsp;<\/p>\n<h4>DISTINCT<\/h4>\n<p><span class=\"TextRun SCXW122592510 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"auto\"><span class=\"NormalTextRun CommentHighlightRest SCXW122592510 BCX8\">Contoso is using <\/span><span class=\"NormalTextRun CommentHighlightRest SCXW122592510 BCX8\">DISTINCT to get the name of <\/span><span class=\"NormalTextRun AdvancedProofingIssueV2Themed CommentHighlightRest SCXW122592510 BCX8\">all of<\/span><span class=\"NormalTextRun CommentHighlightRest SCXW122592510 BCX8\"> their products that are over <\/span><span class=\"NormalTextRun CommentHighlightRest SCXW122592510 BCX8\">$500. Because this query can now take advantage of a single index on Name<\/span><span class=\"NormalTextRun CommentHighlightRest SCXW122592510 BCX8\">, it is much more efficient.<\/span><\/span><span class=\"EOP CommentHighlightRest SCXW122592510 BCX8\" data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<pre class=\"prettyprint\">SELECT\u202fDISTINCT\u202fc.Name\u202f \r\nFROM\u202fc \r\nWHERE\u202fc.Price\u202f&gt;\u202f500<\/pre>\n<p><span data-contrast=\"auto\"><em>Previous query charge:<\/em> 16,545.58 RUs<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <em>Previous execution time:<\/em><span data-contrast=\"auto\"> 47.38 seconds<\/span><span data-ccp-props=\"{&quot;335559739&quot;:0}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\"><em>New query charge:<\/em> 1,005.8 RUs<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span data-contrast=\"auto\"><em>New execution time:<\/em> 11.43 seconds<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<p>&nbsp;<\/p>\n<h3>OFFSET LIMIT optimizations<\/h3>\n<p><span class=\"TextRun SCXW105047236 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW105047236 BCX8\">The query engine will now be able to avoid document loading<\/span><span class=\"NormalTextRun SCXW105047236 BCX8\"> time<\/span><span class=\"NormalTextRun SCXW105047236 BCX8\"> and parsing time for documents outside of the <\/span><span class=\"NormalTextRun SCXW105047236 BCX8\">offset<\/span> <span class=\"NormalTextRun SCXW105047236 BCX8\">range. Queries with large documents and a high offset will see proportional benefits.<\/span> <span class=\"NormalTextRun SCXW105047236 BCX8\">These improvements <\/span><span class=\"NormalTextRun SCXW105047236 BCX8\">can <\/span><span class=\"NormalTextRun SCXW105047236 BCX8\">be seen in queries with some combination of ORDER BY and filter clauses<\/span><span class=\"NormalTextRun SCXW105047236 BCX8\"> like the <\/span><span class=\"NormalTextRun SCXW105047236 BCX8\">query below<\/span><span class=\"NormalTextRun SCXW105047236 BCX8\"> from Contoso<\/span><span class=\"NormalTextRun SCXW105047236 BCX8\"> which gets all products <\/span><span class=\"NormalTextRun AdvancedProofingIssueV2Themed SCXW105047236 BCX8\">in a given<\/span><span class=\"NormalTextRun SCXW105047236 BCX8\"> price range by their <\/span><span class=\"NormalTextRun SpellingErrorV2Themed SCXW105047236 BCX8\">FirstAvailable<\/span><span class=\"NormalTextRun SCXW105047236 BCX8\"> date<\/span><span class=\"NormalTextRun SCXW105047236 BCX8\">.<\/span><span class=\"NormalTextRun SCXW105047236 BCX8\"> Queries with other operators<\/span><span class=\"NormalTextRun SCXW105047236 BCX8\"> such as aggregations, joins, or subqueries <\/span><span class=\"NormalTextRun SCXW105047236 BCX8\">cannot take advantage of these improvements.<\/span><\/span><span class=\"EOP SCXW105047236 BCX8\" data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<pre class=\"prettyprint\">SELECT\u202fc.Name,\u202fc.Price,\u202fc.FirstAvailable \r\nFROM\u202fc \r\nWHERE\u202fc.Price\u202f&gt;\u202f15\u202fAND\u202fc.Price\u202f&lt;\u202f50 \r\nORDER\u202fBY\u202fc.FirstAvailable\u202fDESC \r\nOFFSET\u202f1000\u202fLIMIT\u202f100<\/pre>\n<p><span data-contrast=\"auto\"><em>Previous query charge:<\/em> 332.92 RUs<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<em>Previous execution time: <\/em><span data-contrast=\"auto\">8.63 seconds<\/span><span data-ccp-props=\"{&quot;335559739&quot;:0}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\"><em>New query charge:<\/em> 311.2 RUs<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span data-contrast=\"auto\"><em>New execution time:<\/em> 7.01 seconds<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<p>&nbsp;<\/p>\n<h3>JOIN optimizations<\/h3>\n<p><span class=\"TextRun SCXW13633678 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW13633678 BCX8\">Contoso lets users rate the products sold on their site from 1 \u2013 5 stars. <\/span><span class=\"NormalTextRun SCXW13633678 BCX8\">T<\/span><span class=\"NormalTextRun SCXW13633678 BCX8\">o <\/span><span class=\"NormalTextRun SCXW13633678 BCX8\">make sure their product quality is high, they want to check which of their products that <\/span><span class=\"NormalTextRun SCXW13633678 BCX8\">cost over $100<\/span> <span class=\"NormalTextRun SCXW13633678 BCX8\">have a rating below 3 stars. To achieve <\/span><span class=\"NormalTextRun SCXW13633678 BCX8\">this Contoso can use JOIN to create a cross product of <\/span><span class=\"NormalTextRun SCXW13633678 BCX8\">customer ratings and products in their catalog.\u00a0<\/span><\/span><span class=\"EOP SCXW13633678 BCX8\" data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<pre class=\"prettyprint\">SELECT\u202fc.Name,\u202fc.Price,\u202fr\u202fas\u202fRating \r\nFROM\u202fc \r\nJOIN\u202fr\u202fIN\u202fc.CustomerRatings \r\nWHERE\u202fc.Price\u202f&gt;\u202f100 and r.Stars &lt; 3 \r\n\r\n<\/pre>\n<p><span class=\"TextRun SCXW69257953 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW69257953 BCX8\">Previously, <\/span><span class=\"NormalTextRun SCXW69257953 BCX8\">Contoso<\/span><span class=\"NormalTextRun SCXW69257953 BCX8\"> had re-written this query to use a subquery<\/span><span class=\"NormalTextRun SCXW69257953 BCX8\"> which is more efficient <\/span><span class=\"NormalTextRun SCXW69257953 BCX8\">w<\/span><span class=\"NormalTextRun SCXW69257953 BCX8\">hen there is a<\/span> <span class=\"NormalTextRun SCXW69257953 BCX8\">large arra<\/span><span class=\"NormalTextRun SCXW69257953 BCX8\">y<\/span> <span class=\"NormalTextRun SCXW69257953 BCX8\">and<\/span><span class=\"NormalTextRun SCXW69257953 BCX8\"> a filter<\/span><span class=\"NormalTextRun SCXW69257953 BCX8\"> on a property from th<\/span><span class=\"NormalTextRun SCXW69257953 BCX8\">at<\/span><span class=\"NormalTextRun SCXW69257953 BCX8\"> array<\/span><span class=\"NormalTextRun SCXW69257953 BCX8\">. <\/span><span class=\"NormalTextRun SCXW69257953 BCX8\">With a subquery, the filter is applied before the JOIN to <\/span><span class=\"NormalTextRun SCXW69257953 BCX8\">ignore<\/span><span class=\"NormalTextRun SCXW69257953 BCX8\"> irrelevant rows <\/span><span class=\"NormalTextRun SCXW69257953 BCX8\">before creating the<\/span><span class=\"NormalTextRun SCXW69257953 BCX8\"> cross product instead of<\/span> <span class=\"NormalTextRun SCXW69257953 BCX8\">after the join is applied.<\/span><span class=\"NormalTextRun SCXW69257953 BCX8\"> In this case, Contoso wants to only look at customer ratings below 3 stars.<\/span><\/span><span class=\"EOP SCXW69257953 BCX8\" data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<pre class=\"prettyprint\">SELECT\u202fc.Name,\u202fc.Price,\u202fRating \r\nFROM\u202fc \r\nJOIN\u202f(SELECT\u202fVALUE\u202fr\u202fFROM\u202fr\u202fIN\u202fc.CustomerRatings\u202fWHERE\u202fr.Stars\u202f&lt;\u202f3)\u202fAS\u202fRating \r\nWHERE\u202fc.Price\u202f&gt;\u202f100 \r\n\r\n<\/pre>\n<p><span class=\"TextRun SCXW121168785 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW121168785 BCX8\">Now, with new improvements to JOIN, Contoso no longer <\/span><span class=\"NormalTextRun AdvancedProofingIssueV2Themed SCXW121168785 BCX8\">has to<\/span><span class=\"NormalTextRun SCXW121168785 BCX8\"> explicitly write this subquery themselves. The query engine will now automatically push down the <\/span><span class=\"NormalTextRun SCXW121168785 BCX8\">filters while evaluating the cross product for you. This means that Contoso can now write this query in <\/span><span class=\"NormalTextRun SCXW121168785 BCX8\">its original,<\/span><span class=\"NormalTextRun SCXW121168785 BCX8\"> simpler <\/span><span class=\"NormalTextRun SCXW121168785 BCX8\">form<\/span><span class=\"NormalTextRun SCXW121168785 BCX8\"> to achieve the same performance.<\/span><\/span><span class=\"EOP SCXW121168785 BCX8\" data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<p>&nbsp;<\/p>\n<h3>Learn more<\/h3>\n<ul>\n<li><a class=\"Hyperlink SCXW59650295 BCX8\" href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/cosmos-db\/sql\/sql-query-group-by\" target=\"_blank\" rel=\"noreferrer noopener\"><span class=\"TextRun Underlined SCXW59650295 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW59650295 BCX8\" data-ccp-charstyle=\"Hyperlink\">GROUP BY clause in Azure Cosmos DB | Microsoft Docs<\/span><\/span><\/a><span class=\"EOP SCXW59650295 BCX8\" data-ccp-props=\"{}\">\u00a0<\/span><\/li>\n<li><a class=\"Hyperlink SCXW118268284 BCX8\" href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/cosmos-db\/sql\/sql-query-keywords#distinct\" target=\"_blank\" rel=\"noreferrer noopener\"><span class=\"TextRun Underlined SCXW118268284 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW118268284 BCX8\" data-ccp-charstyle=\"Hyperlink\">SQL keywords for Azure Cosmos DB | Microsoft Docs<\/span><\/span><\/a><span class=\"EOP SCXW118268284 BCX8\" data-ccp-props=\"{}\">\u00a0<\/span><\/li>\n<li><a class=\"Hyperlink SCXW183922715 BCX8\" href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/cosmos-db\/sql\/sql-query-offset-limit\" target=\"_blank\" rel=\"noreferrer noopener\"><span class=\"TextRun Underlined SCXW183922715 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW183922715 BCX8\" data-ccp-charstyle=\"Hyperlink\">OFFSET LIMIT clause in Azure Cosmos DB | Microsoft Docs<\/span><\/span><\/a><span class=\"EOP SCXW183922715 BCX8\" data-ccp-props=\"{}\">\u00a0<\/span><\/li>\n<li><a class=\"Hyperlink SCXW222537048 BCX8\" href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/cosmos-db\/sql\/sql-query-join\" target=\"_blank\" rel=\"noreferrer noopener\"><span class=\"TextRun Underlined SCXW222537048 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW222537048 BCX8\" data-ccp-charstyle=\"Hyperlink\">SQL JOIN queries for Azure Cosmos DB | Microsoft Docs<\/span><\/span><\/a><span class=\"EOP SCXW222537048 BCX8\" data-ccp-props=\"{}\">\u00a0<\/span><\/li>\n<li><a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/cosmos-db\/optimize-dev-test?toc=%2Fazure%2Fcosmos-db%2Fsql%2Ftoc.json\">Optimizing for development and testing in Azure Cosmos DB | Microsoft Docs<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>The query engine in Azure Cosmos DB Core (SQL) API now has a new system function and optimizations for a set of query operations to better use the index. In this post we\u2019ll cover the new DateTimeBin function as well as improvements to GROUP BY, DISTINCT, OFFSET LIMIT, and JOIN. These example scenarios are for [&hellip;]<\/p>\n","protected":false},"author":94159,"featured_media":61,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[12,14],"tags":[],"class_list":["post-4422","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-announcements","category-core-sql-api"],"acf":[],"blog_post_summary":"<p>The query engine in Azure Cosmos DB Core (SQL) API now has a new system function and optimizations for a set of query operations to better use the index. In this post we\u2019ll cover the new DateTimeBin function as well as improvements to GROUP BY, DISTINCT, OFFSET LIMIT, and JOIN. These example scenarios are for [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts\/4422","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\/94159"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/comments?post=4422"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts\/4422\/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=4422"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/categories?post=4422"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/tags?post=4422"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}