{"id":828,"date":"2013-07-19T09:10:54","date_gmt":"2013-07-19T09:10:54","guid":{"rendered":"https:\/\/lucient.com\/en\/interval-queries-in-sql-server-part-1\/"},"modified":"2020-09-28T13:57:01","modified_gmt":"2020-09-28T13:57:01","slug":"interval-queries-in-sql-server-part-1","status":"publish","type":"post","link":"https:\/\/lucient.com\/en\/blog\/interval-queries-in-sql-server-part-1\/","title":{"rendered":"Interval Queries in SQL Server Part 1"},"content":{"rendered":"\n<div class=\"ExternalClassE6D72060FD1649B9AF4EEE7CC04B5044\">\n<p>My good old friend Itzik Ben-Gan wrote an excellent article on interval queries in SQL Server (<a href=\"http:\/\/sqlmag.com\/t-sql\/sql-server-interval-queries\">http:\/\/sqlmag.com\/t-sql\/sql-server-interval-queries<\/a>) by using the Relational Interval Tree model. Based on the model developed by Kriegel, P\u00f6tke, and Seidl, and enhanced by Martin, Itzik fully developed a T-SQL solution. The solution is great, and makes interval queries efficient in all circumstances. However, the solution is quite complex. Itzik made a Microsoft Connect feature proposal (<a href=\"https:\/\/connect.microsoft.com\/SQLServer\/feedback\/details\/780746\">https:\/\/connect.microsoft.com\/SQLServer\/feedback\/details\/780746<\/a>) to add SQL Server Engine support for interval queries. I fully agree that this would be the best solution; now when the theory is known and implementation made possible, it is time that Microsoft puts this in the database engine.<\/p><wp-block data-block=\"core\/more\"><\/wp-block>\n<p>Unfortunately, it looks like temporal data support is not coming in SQL Server soon, at least not yet in the next version (2014). Therefore, it looks like we have to use our own solutions for a while. Itzik&#8217;s fantastic article made me think. I was wondering whether there could be some simpler solutions, even if they are not efficient in all circumstances, even if they are applicable for specific cases only. I found three solutions, and in addition, another good friend from SolidQ, Davide Mauri, presented me the fourth one. In this and next three blog posts I am going to present all four solutions. Please note that I am using the tables and data Itzik has prepared. In order to test the solutions, you can download the code from Itzik&#8217;s article by using the link at the beginning of this post.<\/p>\n<p>Let me start with the classical solution. I am copying the code from Itzik&#8217;s article for creating and populating the table with 10,000,000 rows, and then for querying the middle of the table.<\/p>\n<p><span style=\"font-family: Lucida Console; font-size: 10pt;\"><span style=\"color: blue;\">CREATE<\/span><br>\n<span style=\"color: blue;\">TABLE<\/span><br>\n<span style=\"color: teal;\">dbo<span style=\"color: gray;\">.<span style=\"color: teal;\">Intervals<\/span><br>\n(<\/span><br>\n<\/span><br>\n<span style=\"color: teal;\">id<\/span><br>\n<span style=\"color: blue;\">INT<\/span><br>\n<span style=\"color: gray;\">NOT<\/span><br>\n<span style=\"color: gray;\">NULL,<\/span><br>\n<span style=\"color: fuchsia;\">lower<\/span><br>\n<span style=\"color: blue;\">INT<\/span><br>\n<span style=\"color: gray;\">NOT<\/span><br>\n<span style=\"color: gray;\">NULL,<\/span><br>\n<span style=\"color: fuchsia;\">upper<\/span><br>\n<span style=\"color: blue;\">INT<\/span><br>\n<span style=\"color: gray;\">NOT<\/span><br>\n<span style=\"color: gray;\">NULL,<\/span><br>\n<span style=\"color: blue;\">CONSTRAINT<\/span><br>\n<span style=\"color: teal;\">CHK_Intervals_upper_gteq_lower<\/span><br>\n<span style=\"color: blue;\">CHECK<span style=\"color: gray;\">(<span style=\"color: fuchsia;\">upper<\/span> &gt;=<\/span><br>\n<span style=\"color: fuchsia;\">lower<span style=\"color: gray;\">)<\/span><br>\n<span style=\"color: gray;\">);<\/span><br>\n<\/span><br>\nINSERT<\/span><br>\n<span style=\"color: blue;\">INTO<\/span><br>\n<span style=\"color: teal;\">dbo<span style=\"color: gray;\">.<span style=\"color: teal;\">Intervals<\/span><br>\n<span style=\"color: blue;\">WITH<span style=\"color: gray;\">(<span style=\"color: blue;\">TABLOCK<span style=\"color: gray;\">)<span style=\"color: blue;\"><br>\n<span style=\"color: gray;\">(<span style=\"color: teal;\">id<span style=\"color: gray;\">,<\/span><br>\n<span style=\"color: fuchsia;\">lower<span style=\"color: gray;\">,<\/span> upper<span style=\"color: gray;\">)<\/span><br>\n<\/span><br>\n<span style=\"color: blue;\">SELECT<\/span> id<span style=\"color: gray;\">,<\/span><br>\n<span style=\"color: fuchsia;\">lower<span style=\"color: gray;\">,<\/span> upper<\/span><br>\n<\/span><br>\n<span style=\"color: blue;\">FROM<\/span><br>\n<span style=\"color: teal;\">dbo<span style=\"color: gray;\">.<span style=\"color: teal;\">Stage<span style=\"color: gray;\">;<\/span><br>\n<\/span><br>\n<span style=\"color: blue;\">ALTER<\/span><br>\n<span style=\"color: blue;\">TABLE<\/span><br>\n<span style=\"color: teal;\">dbo<span style=\"color: gray;\">.<span style=\"color: teal;\">Intervals<\/span><br>\n<span style=\"color: blue;\">ADD<\/span><br>\n<span style=\"color: blue;\">CONSTRAINT<\/span><br>\n<span style=\"color: teal;\">PK_Intervals<\/span><br>\n<span style=\"color: blue;\">PRIMARY<\/span><br>\n<span style=\"color: blue;\">KEY<span style=\"color: gray;\">(<span style=\"color: teal;\">id<span style=\"color: gray;\">);<\/span><br>\n<\/span><br>\n<span style=\"color: blue;\">CREATE<\/span><br>\n<span style=\"color: blue;\">INDEX<\/span><br>\n<span style=\"color: teal;\">idx_lower<\/span><br>\n<span style=\"color: blue;\">ON<\/span><br>\n<span style=\"color: teal;\">dbo<span style=\"color: gray;\">.<span style=\"color: teal;\">Intervals<span style=\"color: gray;\">(<span style=\"color: fuchsia;\">lower<span style=\"color: gray;\">)<\/span><br>\n<span style=\"color: blue;\">INCLUDE<span style=\"color: gray;\">(<span style=\"color: fuchsia;\">upper<span style=\"color: gray;\">);<\/span><br>\n<span style=\"color: blue;\">CREATE<\/span><br>\n<span style=\"color: blue;\">INDEX<\/span><br>\n<span style=\"color: teal;\">idx_upper<\/span><br>\n<span style=\"color: blue;\">ON<\/span><br>\n<span style=\"color: teal;\">dbo<span style=\"color: gray;\">.<span style=\"color: teal;\">Intervals<span style=\"color: gray;\">(<span style=\"color: fuchsia;\">upper<span style=\"color: gray;\">)<\/span><br>\n<span style=\"color: blue;\">INCLUDE<span style=\"color: gray;\">(<span style=\"color: fuchsia;\">lower<span style=\"color: gray;\">);<\/span><br>\n<span style=\"color: blue;\">GO<\/span><br>\n<span style=\"color: green;\">&#8212; ~ 60 seconds needed for creating and populating the table<br>\n<\/span><br>\n<span style=\"color: green;\">&#8212; query<\/span><br>\n<span style=\"color: blue;\">SET<\/span><br>\n<span style=\"color: blue;\">STATISTICS<\/span><br>\n<span style=\"color: blue;\">IO<\/span><br>\n<span style=\"color: blue;\">ON<span style=\"color: gray;\">;<\/span><br>\nSET<\/span><br>\n<span style=\"color: blue;\">STATISTICS<\/span><br>\n<span style=\"color: blue;\">TIME<\/span><br>\n<span style=\"color: blue;\">ON<span style=\"color: gray;\">;<\/span><br>\nGO<\/span><br>\n<\/span><br>\n<span style=\"color: green;\">&#8212; middle of data<\/span><br>\n<span style=\"color: blue;\">DECLARE<\/span><br>\n<span style=\"color: teal;\">@l<\/span><br>\n<span style=\"color: blue;\">AS<\/span><br>\n<span style=\"color: blue;\">INT<\/span> =<\/span> 5000000<span style=\"color: gray;\">,<\/span><br>\n<span style=\"color: teal;\">@u<\/span> AS<\/span><br>\n<span style=\"color: blue;\">INT<\/span><br>\n<span style=\"color: gray;\">=<\/span> 5000020<span style=\"color: gray;\">;<\/span><br>\n<\/span><br>\n<span style=\"color: blue;\">SELECT<\/span><br>\n<span style=\"color: teal;\">id<\/span><br>\n<span style=\"color: blue;\">FROM<\/span><br>\n<span style=\"color: teal;\">dbo<span style=\"color: gray;\">.<span style=\"color: teal;\">Intervals<\/span><br>\n<span style=\"color: blue;\">WHERE<\/span><br>\n<span style=\"color: fuchsia;\">lower<\/span> &lt;=<\/span> @u<\/span> AND<\/span><br>\n<span style=\"color: fuchsia;\">upper<\/span><br>\n<span style=\"color: gray;\">&gt;=<\/span> @l<\/span><br>\n<span style=\"color: blue;\">OPTION <span style=\"color: gray;\">(<span style=\"color: blue;\">RECOMPILE<span style=\"color: gray;\">);<\/span><br>\n<span style=\"color: green;\">&#8212; used to allow variable sniffing and prevent plan reuse<\/span><br>\n<span style=\"color: green;\">&#8212; logical reads: 11254, CPU time: 764 ms<\/span><br>\n<\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/p>\n<p>As Itzik has shown, the problem with this query is that SQL Server can use only one index, and successfully eliminate rows that are not candidates for the result from one side only, and then scans the rest (approximately half of the) data. In Itzik&#8217;s and my case presented here, SQL Server used the <em>idx_upper<\/em> index to eliminate the intervals from the left, which satisfy the condition <em>upper &gt;= @l<\/em>. Considering this limitation, usage of a single index for a single query, no matter whether it is <em>idx_lower<\/em> or <em>idx_upper<\/em>, I started to search for a solution which would use that index for elimination of the rows from both sides. The following figure shows an example of possible intervals.<\/p>\n<figure><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-15297 size-full\" src=\"https:\/\/lucient.com\/en\/wp-content\/uploads\/sites\/7\/2020\/09\/071913_1246_IntervalQue1.png\" alt=\"\" width=\"805\" height=\"687\"><\/figure><p><\/p>\n<p>Black color denotes the intervals in the table. The blue colored interval is the one I am checking for the overlaps. The intervals are sorted by the lower boundary, representing SQL Server&#8217;s usage of the <em>idx_lower<\/em> index. Eliminating intervals from the right side of the given (blue) interval is simple: just eliminate all intervals where the beginning is at least one unit bigger (more to the right) of the end of the given interval. You can see this boundary in the figure denoted with yellow line. However, eliminating from the left is more complex. In order to use the same index, the <em>idx_lower<\/em> index for eliminating from the left, I need to use the beginning of the intervals in the table in the <em>WHERE<\/em> clause of the query. I have to go to the left side away from the beginning of the given (blue) interval at least for the length of the longest interval in the table, which is marked with red color in the figure. The intervals that begin before the left yellow line cannot overlap with the given (blue) interval.<\/p>\n<p>Of course, the figure could be turned around to cover the cases when the <em>idx_upper<\/em> index would be more useful. With this index, the elimination from the left is simple \u2013 eliminate all of the intervals which end at least one unit before the beginning of the given interval. This time, the elimination from the right is more complex \u2013 the end of the intervals in the table cannot be more to the right than the end of the given interval plus maximal length of all intervals in the table.<\/p>\n<p>I created a new table with the same structure as the original Itzik&#8217;s table, with just one computed column (<em>ilen<\/em>) added. This column, which calculates the length of an interval, is persisted and indexed in order to speed up the search for the longest interval. The following code creates and populates this table.<\/p>\n<p><span style=\"font-family: Lucida Console; font-size: 10pt;\"><span style=\"color: blue;\">CREATE<\/span><br>\n<span style=\"color: blue;\">TABLE<\/span><br>\n<span style=\"color: teal;\">dbo<span style=\"color: gray;\">.<span style=\"color: teal;\">IntervalsL<\/span><br>\n(<\/span><br>\n<\/span><br>\n<span style=\"color: teal;\">id<\/span><br>\n<span style=\"color: blue;\">INT<\/span><br>\n<span style=\"color: gray;\">NOT<\/span><br>\n<span style=\"color: gray;\">NULL,<\/span><br>\n<span style=\"color: fuchsia;\">lower<\/span><br>\n<span style=\"color: blue;\">INT<\/span><br>\n<span style=\"color: gray;\">NOT<\/span><br>\n<span style=\"color: gray;\">NULL,<\/span><br>\n<span style=\"color: fuchsia;\">upper<\/span><br>\n<span style=\"color: blue;\">INT<\/span><br>\n<span style=\"color: gray;\">NOT<\/span><br>\n<span style=\"color: gray;\">NULL,<\/span><br>\n<span style=\"color: teal;\">ilen<\/span><br>\n<span style=\"color: blue;\">AS<\/span><br>\n<span style=\"color: fuchsia;\">upper<\/span><br>\n<span style=\"color: gray;\">&#8211;<\/span><br>\n<span style=\"color: fuchsia;\">lower<\/span><br>\n<span style=\"color: blue;\">PERSISTED<span style=\"color: gray;\">,<\/span><br>\n<\/span><br>\n<span style=\"color: blue;\">CONSTRAINT<\/span><br>\n<span style=\"color: teal;\">CHK_IntervalsL_upper_gteq_lower<\/span><br>\n<span style=\"color: blue;\">CHECK<span style=\"color: gray;\">(<span style=\"color: fuchsia;\">upper<\/span> &gt;=<\/span><br>\n<span style=\"color: fuchsia;\">lower<span style=\"color: gray;\">)<\/span><br>\n<span style=\"color: gray;\">);<\/span><br>\n<\/span><br>\nINSERT<\/span><br>\n<span style=\"color: blue;\">INTO<\/span><br>\n<span style=\"color: teal;\">dbo<span style=\"color: gray;\">.<span style=\"color: teal;\">IntervalsL<\/span><br>\n<span style=\"color: blue;\">WITH<span style=\"color: gray;\">(<span style=\"color: blue;\">TABLOCK<span style=\"color: gray;\">)<span style=\"color: blue;\"><br>\n<span style=\"color: gray;\">(<span style=\"color: teal;\">id<span style=\"color: gray;\">,<\/span><br>\n<span style=\"color: fuchsia;\">lower<span style=\"color: gray;\">,<\/span> upper<span style=\"color: gray;\">)<\/span><br>\n<\/span><br>\n<span style=\"color: blue;\">SELECT<\/span> id<span style=\"color: gray;\">,<\/span><br>\n<span style=\"color: fuchsia;\">lower<span style=\"color: gray;\">,<\/span> upper<\/span><br>\n<\/span><br>\n<span style=\"color: blue;\">FROM<\/span><br>\n<span style=\"color: teal;\">dbo<span style=\"color: gray;\">.<span style=\"color: teal;\">Stage<span style=\"color: gray;\">;<\/span><br>\n<\/span><br>\n<span style=\"color: blue;\">ALTER<\/span><br>\n<span style=\"color: blue;\">TABLE<\/span><br>\n<span style=\"color: teal;\">dbo<span style=\"color: gray;\">.<span style=\"color: teal;\">IntervalsL<\/span><br>\n<span style=\"color: blue;\">ADD<\/span><br>\n<span style=\"color: blue;\">CONSTRAINT<\/span><br>\n<span style=\"color: teal;\">PK_IntervalsL<\/span><br>\n<span style=\"color: blue;\">PRIMARY<\/span><br>\n<span style=\"color: blue;\">KEY<span style=\"color: gray;\">(<span style=\"color: teal;\">id<span style=\"color: gray;\">);<\/span><br>\n<\/span><br>\n<span style=\"color: blue;\">CREATE<\/span><br>\n<span style=\"color: blue;\">INDEX<\/span><br>\n<span style=\"color: teal;\">idx_lowerL<\/span><br>\n<span style=\"color: blue;\">ON<\/span><br>\n<span style=\"color: teal;\">dbo<span style=\"color: gray;\">.<span style=\"color: teal;\">IntervalsL<span style=\"color: gray;\">(<span style=\"color: fuchsia;\">lower<span style=\"color: gray;\">)<\/span><br>\n<span style=\"color: blue;\">INCLUDE<span style=\"color: gray;\">(<span style=\"color: fuchsia;\">upper<span style=\"color: gray;\">);<\/span><br>\n<span style=\"color: blue;\">CREATE<\/span><br>\n<span style=\"color: blue;\">INDEX<\/span><br>\n<span style=\"color: teal;\">idx_upperL<\/span><br>\n<span style=\"color: blue;\">ON<\/span><br>\n<span style=\"color: teal;\">dbo<span style=\"color: gray;\">.<span style=\"color: teal;\">IntervalsL<span style=\"color: gray;\">(<span style=\"color: fuchsia;\">upper<span style=\"color: gray;\">)<\/span><br>\n<span style=\"color: blue;\">INCLUDE<span style=\"color: gray;\">(<span style=\"color: fuchsia;\">lower<span style=\"color: gray;\">);<\/span><br>\n<span style=\"color: blue;\">CREATE<\/span><br>\n<span style=\"color: blue;\">INDEX<\/span><br>\n<span style=\"color: teal;\">ids_ilenL<\/span><br>\n<span style=\"color: blue;\">ON<\/span><br>\n<span style=\"color: teal;\">dbo<span style=\"color: gray;\">.<span style=\"color: teal;\">IntervalsL<span style=\"color: gray;\">(<span style=\"color: teal;\">ilen<span style=\"color: gray;\">);<\/span><br>\n<span style=\"color: blue;\">GO<\/span><br>\n<span style=\"color: green;\">&#8212; ~ 80 seconds needed for creating and populating the table<br>\n<\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/p>\n<p>&nbsp;<\/p>\n<p>The creating and the population of the table was slightly longer. Of course, this is due to the creation of the additional index. In addition, because of the persisted computed column, the rows are longer and thus SQL Server needed to allocate more pages for the same 10,000,000 rows.<\/p>\n<p>I find the maximal length of the intervals in advance and then store it in a variable. The query that checks for the overlaps in the middle of the data uses just slightly more complex <em>WHERE<\/em> clause, otherwise it is equal to the original query, as you can see from the following code.<\/p>\n<p><span style=\"font-family: Lucida Console;\"><span style=\"font-size: 10pt;\"><span style=\"color: green;\">&#8212; query<\/span><br>\n<span style=\"color: blue;\">SET<\/span><br>\n<span style=\"color: blue;\">STATISTICS<\/span><br>\n<span style=\"color: blue;\">IO<\/span><br>\n<span style=\"color: blue;\">ON<span style=\"color: gray;\">;<\/span><br>\nSET<\/span><br>\n<span style=\"color: blue;\">STATISTICS<\/span><br>\n<span style=\"color: blue;\">TIME<\/span><br>\n<span style=\"color: blue;\">ON<span style=\"color: gray;\">;<\/span><br>\nGO<\/span><\/span><\/span><\/p>\n<p><span style=\"color: green;\">&#8212; middle of data<\/span><br>\n<span style=\"color: blue;\">DECLARE<\/span><br>\n<span style=\"color: teal;\">@l<\/span><br>\n<span style=\"color: blue;\">AS<\/span><br>\n<span style=\"color: blue;\">INT<\/span><br>\n<span style=\"color: gray;\">=<\/span> 5000000<span style=\"color: gray;\">,<\/span><br>\n<span style=\"color: teal;\">@u<\/span><br>\n<span style=\"color: blue;\">AS<\/span><br>\n<span style=\"color: blue;\">INT<\/span><br>\n<span style=\"color: gray;\">=<\/span> 5000020<span style=\"color: gray;\">;<\/span><\/p>\n<p><span style=\"color: blue;\">DECLARE<\/span><br>\n<span style=\"color: teal;\">@max<\/span><br>\n<span style=\"color: blue;\">AS<\/span><br>\n<span style=\"color: blue;\">INT<span style=\"color: gray;\">;<\/span><br>\nSET<\/span><br>\n<span style=\"color: teal;\">@max<\/span><br>\n<span style=\"color: gray;\">=<\/span><\/p>\n<p><span style=\"color: blue;\"><br>\n<span style=\"color: gray;\">(<span style=\"color: blue;\">SELECT<\/span><br>\n<span style=\"color: fuchsia;\">MAX<span style=\"color: gray;\">(<span style=\"color: teal;\">ilen<span style=\"color: gray;\">)<\/span><br>\n<span style=\"color: blue;\">AS<\/span> maxlen<\/span><br>\n<span style=\"color: blue;\">FROM<\/span><br>\n<span style=\"color: blue;\"><br>\n<span style=\"color: gray;\">(<span style=\"color: blue;\">SELECT<\/span><br>\n<span style=\"color: fuchsia;\">MAX<span style=\"color: gray;\">(<span style=\"color: teal;\">ilen<span style=\"color: gray;\">)<\/span><br>\n<span style=\"color: blue;\">AS<\/span> ilen<\/span><br>\n<span style=\"color: blue;\">FROM<\/span><br>\n<span style=\"color: teal;\">dbo<span style=\"color: gray;\">.<span style=\"color: teal;\">IntervalsL<\/span><br>\n<\/span><br>\n<span style=\"color: blue;\">UNION<\/span><br>\n<\/span><br>\n<span style=\"color: blue;\">SELECT<\/span><br>\n<span style=\"color: teal;\">@u<\/span> &#8211;<\/span><br>\n<span style=\"color: teal;\">@l<span style=\"color: gray;\">)<\/span><br>\n<span style=\"color: blue;\">AS<\/span> m1<\/span><br>\n<\/span> );<\/span><br>\n<\/span><br>\n<span style=\"color: blue;\">SELECT<\/span><br>\n<span style=\"color: teal;\">id<\/span><br>\n<span style=\"color: blue;\">FROM<\/span><br>\n<span style=\"color: teal;\">dbo<span style=\"color: gray;\">.<span style=\"color: teal;\">Intervals<\/span><br>\n<span style=\"color: blue;\">WHERE<\/span><br>\n<span style=\"color: fuchsia;\">lower<\/span> &lt;=<\/span> @u<\/span> AND<\/span> lower<\/span> &gt;=<\/span><br>\n<span style=\"color: teal;\">@l<\/span><br>\n<span style=\"color: gray;\">&#8211;<\/span><br>\n<span style=\"color: teal;\">@max<\/span><br>\n<\/span><br>\n<span style=\"color: gray;\">AND<\/span><br>\n<span style=\"color: fuchsia;\">upper<\/span><br>\n<span style=\"color: gray;\">&gt;=<\/span><br>\n<span style=\"color: teal;\">@l<\/span><br>\n<span style=\"color: gray;\">AND<\/span><br>\n<span style=\"color: fuchsia;\">upper<\/span><br>\n<span style=\"color: gray;\">&lt;=<\/span><br>\n<span style=\"color: teal;\">@u<\/span><br>\n<span style=\"color: gray;\">+<\/span><br>\n<span style=\"color: teal;\">@max<\/span><br>\n<span style=\"color: blue;\">OPTION <span style=\"color: gray;\">(<span style=\"color: blue;\">RECOMPILE<span style=\"color: gray;\">);<\/span><br>\nGO<\/span><br>\n<span style=\"color: green;\">&#8212; logical reads: 6 (3 + 3 to calculate the max length), CPU time: 0 ms<br>\n<\/span><\/span><\/span><span style=\"font-size: 14pt;\"><br>\n<\/span><\/p>\n<p>Note the performance of the query. With Itzik&#8217;s data, it needed only 6 logical reads, and was thus performing much better that even the fastest solution using the RI tree model, as you can see in the Itzik&#8217;s article. However, please note that this performance is the consequence of the specific data in the table. The maximal length of an interval is 20, and there are 10,000,000 intervals in the table. This way, SQL Server can very efficiently eliminate intervals from both sides. However, if there would be only one long interval in the table, the code would become much less efficient, because SQL Server would not be able to eliminate a lot of rows from one side, either left or right, depending which index it would use. For example, the following code sets the maximal length of the intervals in the table to a predefined size 100,000, and then executes the same query.<\/p>\n<p><span style=\"font-family: Lucida Console; font-size: 10pt;\"><span style=\"color: green;\">&#8212; Check with longer maximal interval<\/span><br>\n<span style=\"color: blue;\">DECLARE<\/span><br>\n<span style=\"color: teal;\">@l<\/span><br>\n<span style=\"color: blue;\">AS<\/span><br>\n<span style=\"color: blue;\">INT<\/span><br>\n<span style=\"color: gray;\">=<\/span> 5000000<span style=\"color: gray;\">,<\/span><br>\n<span style=\"color: teal;\">@u<\/span><br>\n<span style=\"color: blue;\">AS<\/span><br>\n<span style=\"color: blue;\">INT<\/span><br>\n<span style=\"color: gray;\">=<\/span> 5000020<span style=\"color: gray;\">;<\/span><\/span><\/p>\n<p><span style=\"color: blue;\">DECLARE<\/span><br>\n<span style=\"color: teal;\">@max<\/span><br>\n<span style=\"color: blue;\">AS<\/span><br>\n<span style=\"color: blue;\">INT<\/span><br>\n<span style=\"color: gray;\">=<\/span> 100000<span style=\"color: gray;\">;<\/span><\/p>\n<p><span style=\"color: blue;\">SELECT<\/span><br>\n<span style=\"color: teal;\">id<\/span><br>\n<span style=\"color: blue;\">FROM<\/span><br>\n<span style=\"color: teal;\">dbo<span style=\"color: gray;\">.<span style=\"color: teal;\">Intervals<\/span><br>\n<span style=\"color: blue;\">WHERE<\/span><br>\n<span style=\"color: fuchsia;\">lower<\/span> &lt;=<\/span> @u<\/span><br>\n<span style=\"color: gray;\">AND<\/span><br>\n<span style=\"color: fuchsia;\">lower<\/span><br>\n<span style=\"color: gray;\">&gt;=<\/span><br>\n<span style=\"color: teal;\">@l<\/span><br>\n<span style=\"color: gray;\">&#8211;<\/span><br>\n<span style=\"color: teal;\">@max<\/span><br>\n<span style=\"color: gray;\">AND<\/span><br>\n<span style=\"color: fuchsia;\">upper<\/span><br>\n<span style=\"color: gray;\">&gt;=<\/span><br>\n<span style=\"color: teal;\">@l<\/span><br>\n<span style=\"color: gray;\">AND<\/span><br>\n<span style=\"color: fuchsia;\">upper<\/span><br>\n<span style=\"color: gray;\">&lt;=<\/span><br>\n<span style=\"color: teal;\">@u<\/span><br>\n<span style=\"color: gray;\">+<\/span><br>\n<span style=\"color: teal;\">@max<\/span><br>\n<span style=\"color: blue;\">OPTION <span style=\"color: gray;\">(<span style=\"color: blue;\">RECOMPILE<span style=\"color: gray;\">);<\/span><br>\nGO<\/span><br>\n<span style=\"color: green;\">&#8212; logical reads: 228, CPU time: 0 ms<br>\n<\/span><\/span><\/span><\/p>\n<p>The number of logical reads has grown substantially. In worst case, with a very long interval in the table, the performance of the query would be comparable to the performance of the classical solution presented in the beginning of this blog and in the beginning of the Itzik&#8217;s article.<\/p>\n<p>To conclude, this solution might be very useful in case when your data has more or less uniform distribution of the lengths, or, as in the case with Itzik&#8217;s test data, when the distribution is not uniform but the maximal length is small. If this is the case, you might prefer this solution to the RI tree model solution, because it is much simpler. However, as I already stated in this blog post, Itzik&#8217;s solution does not depend on any data distribution. Therefore, if you don&#8217;t know or control the distribution of your data, you should go for the RI tree model solution.<\/p>\n<p>I will show more solutions in the forthcoming blogs.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>My good old friend Itzik Ben-Gan wrote an excellent article on interval queries in SQL Server (http:\/\/sqlmag.com\/t-sql\/sql-server-interval-queries) by using the Relational Interval Tree model. Based on the model developed by Kriegel, P\u00f6tke, and Seidl, and enhanced by Martin, Itzik fully developed a T-SQL solution. The solution is great, and makes interval queries efficient in all [&hellip;]<\/p>\n","protected":false},"author":9,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"content-type":"","footnotes":""},"categories":[8],"tags":[],"class_list":["post-828","post","type-post","status-publish","format-standard","hentry","category-technical"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Interval Queries in SQL Server Part 1 - Lucient - North America<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/lucient.com\/en\/blog\/interval-queries-in-sql-server-part-1\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Interval Queries in SQL Server Part 1 - Lucient - North America\" \/>\n<meta property=\"og:description\" content=\"My good old friend Itzik Ben-Gan wrote an excellent article on interval queries in SQL Server (http:\/\/sqlmag.com\/t-sql\/sql-server-interval-queries) by using the Relational Interval Tree model. Based on the model developed by Kriegel, P\u00f6tke, and Seidl, and enhanced by Martin, Itzik fully developed a T-SQL solution. The solution is great, and makes interval queries efficient in all [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/lucient.com\/en\/blog\/interval-queries-in-sql-server-part-1\/\" \/>\n<meta property=\"og:site_name\" content=\"Lucient - North America\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/LucientData\" \/>\n<meta property=\"article:published_time\" content=\"2013-07-19T09:10:54+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-09-28T13:57:01+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/lucient.com\/en\/wp-content\/uploads\/sites\/7\/2020\/09\/071913_1246_IntervalQue1.png\" \/>\n<meta name=\"author\" content=\"dsarka\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@lucient_data\" \/>\n<meta name=\"twitter:site\" content=\"@lucient_data\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"dsarka\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/lucient.com\\\/en\\\/blog\\\/interval-queries-in-sql-server-part-1\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/lucient.com\\\/en\\\/blog\\\/interval-queries-in-sql-server-part-1\\\/\"},\"author\":{\"name\":\"dsarka\",\"@id\":\"https:\\\/\\\/lucient.com\\\/en\\\/#\\\/schema\\\/person\\\/abd50575df3732f3d3191fa1878f3cf8\"},\"headline\":\"Interval Queries in SQL Server Part 1\",\"datePublished\":\"2013-07-19T09:10:54+00:00\",\"dateModified\":\"2020-09-28T13:57:01+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/lucient.com\\\/en\\\/blog\\\/interval-queries-in-sql-server-part-1\\\/\"},\"wordCount\":1531,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/lucient.com\\\/en\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/lucient.com\\\/en\\\/blog\\\/interval-queries-in-sql-server-part-1\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/lucient.com\\\/en\\\/wp-content\\\/uploads\\\/sites\\\/7\\\/2020\\\/09\\\/071913_1246_IntervalQue1.png\",\"articleSection\":[\"Technical\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/lucient.com\\\/en\\\/blog\\\/interval-queries-in-sql-server-part-1\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/lucient.com\\\/en\\\/blog\\\/interval-queries-in-sql-server-part-1\\\/\",\"url\":\"https:\\\/\\\/lucient.com\\\/en\\\/blog\\\/interval-queries-in-sql-server-part-1\\\/\",\"name\":\"Interval Queries in SQL Server Part 1 - Lucient - North America\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/lucient.com\\\/en\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/lucient.com\\\/en\\\/blog\\\/interval-queries-in-sql-server-part-1\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/lucient.com\\\/en\\\/blog\\\/interval-queries-in-sql-server-part-1\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/lucient.com\\\/en\\\/wp-content\\\/uploads\\\/sites\\\/7\\\/2020\\\/09\\\/071913_1246_IntervalQue1.png\",\"datePublished\":\"2013-07-19T09:10:54+00:00\",\"dateModified\":\"2020-09-28T13:57:01+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/lucient.com\\\/en\\\/blog\\\/interval-queries-in-sql-server-part-1\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/lucient.com\\\/en\\\/blog\\\/interval-queries-in-sql-server-part-1\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/lucient.com\\\/en\\\/blog\\\/interval-queries-in-sql-server-part-1\\\/#primaryimage\",\"url\":\"https:\\\/\\\/lucient.com\\\/en\\\/wp-content\\\/uploads\\\/sites\\\/7\\\/2020\\\/09\\\/071913_1246_IntervalQue1.png\",\"contentUrl\":\"https:\\\/\\\/lucient.com\\\/en\\\/wp-content\\\/uploads\\\/sites\\\/7\\\/2020\\\/09\\\/071913_1246_IntervalQue1.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/lucient.com\\\/en\\\/blog\\\/interval-queries-in-sql-server-part-1\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/lucient.com\\\/en\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Interval Queries in SQL Server Part 1\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/lucient.com\\\/en\\\/#website\",\"url\":\"https:\\\/\\\/lucient.com\\\/en\\\/\",\"name\":\"Lucient - North America\",\"description\":\"Empowering businesses with data analytics\",\"publisher\":{\"@id\":\"https:\\\/\\\/lucient.com\\\/en\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/lucient.com\\\/en\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/lucient.com\\\/en\\\/#organization\",\"name\":\"Lucient\",\"url\":\"https:\\\/\\\/lucient.com\\\/en\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/lucient.com\\\/en\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/lucient.com\\\/wp-content\\\/uploads\\\/2021\\\/02\\\/Lucient-Logo-Pos-RGB.png\",\"contentUrl\":\"https:\\\/\\\/lucient.com\\\/wp-content\\\/uploads\\\/2021\\\/02\\\/Lucient-Logo-Pos-RGB.png\",\"width\":2540,\"height\":568,\"caption\":\"Lucient\"},\"image\":{\"@id\":\"https:\\\/\\\/lucient.com\\\/en\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/LucientData\",\"https:\\\/\\\/x.com\\\/lucient_data\",\"https:\\\/\\\/instagra.com\\\/lucient_data\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/lucientdata\",\"https:\\\/\\\/youtube.com\\\/channel\\\/UCLr1d81OFqPo13IQ9-htVWQ\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/lucient.com\\\/en\\\/#\\\/schema\\\/person\\\/abd50575df3732f3d3191fa1878f3cf8\",\"name\":\"dsarka\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/4a8af2b240a5f32db136e340c424195adbc5b560b0833c0723dfa87fab9963c6?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/4a8af2b240a5f32db136e340c424195adbc5b560b0833c0723dfa87fab9963c6?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/4a8af2b240a5f32db136e340c424195adbc5b560b0833c0723dfa87fab9963c6?s=96&d=mm&r=g\",\"caption\":\"dsarka\"},\"url\":\"https:\\\/\\\/lucient.com\\\/en\\\/blog\\\/author\\\/dsarka\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Interval Queries in SQL Server Part 1 - Lucient - North America","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/lucient.com\/en\/blog\/interval-queries-in-sql-server-part-1\/","og_locale":"en_US","og_type":"article","og_title":"Interval Queries in SQL Server Part 1 - Lucient - North America","og_description":"My good old friend Itzik Ben-Gan wrote an excellent article on interval queries in SQL Server (http:\/\/sqlmag.com\/t-sql\/sql-server-interval-queries) by using the Relational Interval Tree model. Based on the model developed by Kriegel, P\u00f6tke, and Seidl, and enhanced by Martin, Itzik fully developed a T-SQL solution. The solution is great, and makes interval queries efficient in all [&hellip;]","og_url":"https:\/\/lucient.com\/en\/blog\/interval-queries-in-sql-server-part-1\/","og_site_name":"Lucient - North America","article_publisher":"https:\/\/www.facebook.com\/LucientData","article_published_time":"2013-07-19T09:10:54+00:00","article_modified_time":"2020-09-28T13:57:01+00:00","og_image":[{"url":"https:\/\/lucient.com\/en\/wp-content\/uploads\/sites\/7\/2020\/09\/071913_1246_IntervalQue1.png","type":"","width":"","height":""}],"author":"dsarka","twitter_card":"summary_large_image","twitter_creator":"@lucient_data","twitter_site":"@lucient_data","twitter_misc":{"Written by":"dsarka","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/lucient.com\/en\/blog\/interval-queries-in-sql-server-part-1\/#article","isPartOf":{"@id":"https:\/\/lucient.com\/en\/blog\/interval-queries-in-sql-server-part-1\/"},"author":{"name":"dsarka","@id":"https:\/\/lucient.com\/en\/#\/schema\/person\/abd50575df3732f3d3191fa1878f3cf8"},"headline":"Interval Queries in SQL Server Part 1","datePublished":"2013-07-19T09:10:54+00:00","dateModified":"2020-09-28T13:57:01+00:00","mainEntityOfPage":{"@id":"https:\/\/lucient.com\/en\/blog\/interval-queries-in-sql-server-part-1\/"},"wordCount":1531,"commentCount":0,"publisher":{"@id":"https:\/\/lucient.com\/en\/#organization"},"image":{"@id":"https:\/\/lucient.com\/en\/blog\/interval-queries-in-sql-server-part-1\/#primaryimage"},"thumbnailUrl":"https:\/\/lucient.com\/en\/wp-content\/uploads\/sites\/7\/2020\/09\/071913_1246_IntervalQue1.png","articleSection":["Technical"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/lucient.com\/en\/blog\/interval-queries-in-sql-server-part-1\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/lucient.com\/en\/blog\/interval-queries-in-sql-server-part-1\/","url":"https:\/\/lucient.com\/en\/blog\/interval-queries-in-sql-server-part-1\/","name":"Interval Queries in SQL Server Part 1 - Lucient - North America","isPartOf":{"@id":"https:\/\/lucient.com\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/lucient.com\/en\/blog\/interval-queries-in-sql-server-part-1\/#primaryimage"},"image":{"@id":"https:\/\/lucient.com\/en\/blog\/interval-queries-in-sql-server-part-1\/#primaryimage"},"thumbnailUrl":"https:\/\/lucient.com\/en\/wp-content\/uploads\/sites\/7\/2020\/09\/071913_1246_IntervalQue1.png","datePublished":"2013-07-19T09:10:54+00:00","dateModified":"2020-09-28T13:57:01+00:00","breadcrumb":{"@id":"https:\/\/lucient.com\/en\/blog\/interval-queries-in-sql-server-part-1\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/lucient.com\/en\/blog\/interval-queries-in-sql-server-part-1\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/lucient.com\/en\/blog\/interval-queries-in-sql-server-part-1\/#primaryimage","url":"https:\/\/lucient.com\/en\/wp-content\/uploads\/sites\/7\/2020\/09\/071913_1246_IntervalQue1.png","contentUrl":"https:\/\/lucient.com\/en\/wp-content\/uploads\/sites\/7\/2020\/09\/071913_1246_IntervalQue1.png"},{"@type":"BreadcrumbList","@id":"https:\/\/lucient.com\/en\/blog\/interval-queries-in-sql-server-part-1\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/lucient.com\/en\/"},{"@type":"ListItem","position":2,"name":"Interval Queries in SQL Server Part 1"}]},{"@type":"WebSite","@id":"https:\/\/lucient.com\/en\/#website","url":"https:\/\/lucient.com\/en\/","name":"Lucient - North America","description":"Empowering businesses with data analytics","publisher":{"@id":"https:\/\/lucient.com\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/lucient.com\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/lucient.com\/en\/#organization","name":"Lucient","url":"https:\/\/lucient.com\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/lucient.com\/en\/#\/schema\/logo\/image\/","url":"https:\/\/lucient.com\/wp-content\/uploads\/2021\/02\/Lucient-Logo-Pos-RGB.png","contentUrl":"https:\/\/lucient.com\/wp-content\/uploads\/2021\/02\/Lucient-Logo-Pos-RGB.png","width":2540,"height":568,"caption":"Lucient"},"image":{"@id":"https:\/\/lucient.com\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/LucientData","https:\/\/x.com\/lucient_data","https:\/\/instagra.com\/lucient_data","https:\/\/www.linkedin.com\/company\/lucientdata","https:\/\/youtube.com\/channel\/UCLr1d81OFqPo13IQ9-htVWQ"]},{"@type":"Person","@id":"https:\/\/lucient.com\/en\/#\/schema\/person\/abd50575df3732f3d3191fa1878f3cf8","name":"dsarka","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/4a8af2b240a5f32db136e340c424195adbc5b560b0833c0723dfa87fab9963c6?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/4a8af2b240a5f32db136e340c424195adbc5b560b0833c0723dfa87fab9963c6?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/4a8af2b240a5f32db136e340c424195adbc5b560b0833c0723dfa87fab9963c6?s=96&d=mm&r=g","caption":"dsarka"},"url":"https:\/\/lucient.com\/en\/blog\/author\/dsarka\/"}]}},"_links":{"self":[{"href":"https:\/\/lucient.com\/en\/wp-json\/wp\/v2\/posts\/828","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lucient.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lucient.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lucient.com\/en\/wp-json\/wp\/v2\/users\/9"}],"replies":[{"embeddable":true,"href":"https:\/\/lucient.com\/en\/wp-json\/wp\/v2\/comments?post=828"}],"version-history":[{"count":0,"href":"https:\/\/lucient.com\/en\/wp-json\/wp\/v2\/posts\/828\/revisions"}],"wp:attachment":[{"href":"https:\/\/lucient.com\/en\/wp-json\/wp\/v2\/media?parent=828"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lucient.com\/en\/wp-json\/wp\/v2\/categories?post=828"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lucient.com\/en\/wp-json\/wp\/v2\/tags?post=828"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}