{"id":1080,"date":"2016-12-07T00:00:00","date_gmt":"2016-12-07T00:00:00","guid":{"rendered":"https:\/\/en.pingcap.com\/blog\/subquery-optimization-in-tidb\/"},"modified":"2023-07-20T20:47:34","modified_gmt":"2023-07-21T03:47:34","slug":"subquery-optimization-in-tidb","status":"publish","type":"post","link":"https:\/\/www.pingcap.com\/ko\/blog\/subquery-optimization-in-tidb\/","title":{"rendered":"Subquery Optimization in TiDB"},"content":{"rendered":"<h2><span class=\"ez-toc-section\" id=\"Introduction_to_subqueries\"><\/span>Introduction to subqueries<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Subquery is a query within another SQL query. A common subquery is embedded within the <code>FROM<\/code> clause, for example:<\/p>\n<pre><code>SELECT ID FROM (SELECT * FROM SRC) AS T\n<\/code><\/pre>\n<p>The subexpressions in the <code>FROM<\/code> clauses can be processed very well by the general SQL optimizers. But when it comes to subqueries in the <code>WHERE<\/code> clause or the <code>SELECT<\/code> lists, it becomes very difficult to optimize because subqueries can be anywhere in the expression, e.g. in the <code>CASE...WHEN...<\/code> clauses.<\/p>\n<p>The subqueries that are not in the <code>FROM<\/code> clause are categorized as &#8220;correlated subquery&#8221; and &#8220;uncorrelated subquery&#8221;. Correlated subquery refers to a subquery with columns from outer references, for example:<\/p>\n<pre><code>SELECT * FROM SRC WHERE\n\nEXISTS(SELECT * FROM TMP WHERE TMP.id = SRC.id)\n<\/code><\/pre>\n<p>Uncorrelated subqueries can be pre-processed in the plan phase and be re-written to a constant. Therefore, this article is mainly focused on the optimization of correlated subqueries.<\/p>\n<p>Generally speaking, there are following three types of subqueries:<\/p>\n<ul>\n<li>Scalar Subquery like (<code>SELECT...<\/code>) + (<code>SELECT...<\/code>)<\/li>\n<li>Quantified Comparison like <code>T.a = ANY(SELECT...)<\/code><\/li>\n<li>Existential Test like <code>NOT EXISTS(SELECT...)<\/code>, <code>T.a IN (SELECT...)<\/code><\/li>\n<\/ul>\n<p>For the simple subqueries like Existential Test, the common practice is to rewrite them to <code>SemiJoin<\/code>. But it is barely explored in the literature about the generic algorithm and what kind of subqueries need to remove the correlation. For those subqueries whose correlation cannot be removed, the common practice in databases is to execute in Nested Loop, which is called correlated execution.<\/p>\n<p>TiDB inherits the subquery strategy in SQL Server [^1]. It introduces the <code>Apply<\/code> operator to use algebraic representation for subqueries which is called normalization, and then removes the correlation based on the cost information.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"The_Apply_operator\"><\/span>The <code>Apply<\/code> operator<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The reason why subqueries are difficult to optimize is that a subquery cannot be represented as a logic operator like <code>Projection<\/code> or <code>Join<\/code>, which makes it difficult to find a generic algorithm for subquery transformation. So the first thing is to introduce a logical operation that can represent the subqueries: the <code>Apply<\/code> operator, which is also called <code>d-Join<\/code>[^2].<\/p>\n<p>The semantics of the <code>Apply<\/code> operator is:<\/p>\n<p>$$<br \/>\nR A^{otimes} E = bigcuplimits_{rin R} ({r}otimes E(r))<br \/>\n$$<\/p>\n<p>where <code>E<\/code> represents a parameterized subquery. In every execution, the <code>Apply<\/code> operator gets an <code>r<\/code> record from the <code>R<\/code> relation and sends <code>r<\/code> to <code>E<\/code> as a parameter for the \u2297 operation of <code>r<\/code> and <code>E(r)<\/code>. \u2297 is different based on different query types, usually it&#8217;s <code>SemiJoin<\/code> <code>\u2203<\/code>.<\/p>\n<p>For the following SQL statement:<\/p>\n<pre><code>SELECT * FROM SRC WHERE\n\nEXISTS(SELECT * FROM TMP WHERE TMP.id = SRC.id)\n<\/code><\/pre>\n<p>the <code>Apply<\/code> operator representation is as follows:<\/p>\n<p>Because the operator above <code>Apply<\/code> is <code>Selection<\/code>, formally, it is:<\/p>\n<p>$$<br \/>\nSRC A^exists sigma_{SRC.id=TMP.id}TMP<br \/>\n$$<\/p>\n<p>For the <code>EXISTS<\/code> subquery in the <code>SELECT<\/code> list, and the data that cannot pass through the <code>SRC.id=TMP.id<\/code> equation, the output should be false. So <code>OuterJoin<\/code> should be used:<\/p>\n<p>$$<br \/>\npi_C({SRC} A^{LOJ} sigma_{SRC.id=TMP.id}TMP)<br \/>\n$$<\/p>\n<p>The <code>C<\/code> Projection is to transform NULL to false. But the more common practice is: If the output of the <code>Apply<\/code> operator is directly used by the query predicate, it is converted to <code>SemiJoin<\/code>.<\/p>\n<div class=\"trackable-btns\"><a href=\"\/download\"><button>Download TiDB<\/button><\/a><br \/>\n<a href=\"https:\/\/share.hsforms.com\/1e2W03wLJQQKPd1d9rCbj_Q2npzm\"><button>Subscribe to Blog<\/button><\/a><\/div>\n<h2><span class=\"ez-toc-section\" id=\"Removing_the_correlation\"><\/span>Removing the correlation<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The introduction of the <code>Apply<\/code> operator enables us to remove the correlation of the subqueries. The two examples in the previous section can be transformed to:<\/p>\n<p>$$<br \/>\nSRC exists sigma_{SRC.id = TMP.id} TMP<br \/>\n$$<\/p>\n<p>and<\/p>\n<p>$$<br \/>\nSRC LOJ sigma_{SRC.id = TMP.id} TMP<br \/>\n$$<\/p>\n<p>Other rules to remove correlation can be formally represented as:<\/p>\n<p>$R A^{otimes} E= R {otimes}_{true} E$, if no parameters in <code>E<\/code> resolved from <code>R<\/code> (1)<\/p>\n<p>$R A^{otimes} (sigma_pE) = R {otimes}_p E$, if no parameters in <code>E<\/code> resolved from <code>R<\/code> (2)<\/p>\n<p>$R A^times (sigma_pE)=sigma_p(R A^times E)$ (3)<\/p>\n<p>$R A^times (pi_vE) = pi_{vbigcupmathrm{cols}(R)}(R A^times E)$ (4)<\/p>\n<p>$R A^times (E_1 bigcup E_2) = (R A^times E_1) bigcup (R A^times E_2)$ (5)<\/p>\n<p>$R A^times (E_1 &#8211; E_2) = (R A^times E_1) &#8211; (R A^times E_2)$ (6)<\/p>\n<p>$R A^times (E_1 times E_2) = (R A^times E_1) Join_{R.key} (R A^times E_2)$ (7)<\/p>\n<p>$R A^times (mathcal{G}<em>{A,F}E) = mathcal{G}<\/em>{Abigcup mathrm{attr}(R),F} (R A^{times} E)$ (8)<\/p>\n<p>$R A^times (mathcal{G}^1_FE) = mathcal{G}_{Abigcup mathrm{attr}(R),F&#8217;} (R A^{LOJ} E)$ (9)<\/p>\n<p>Based on the above rules, the correlation among all the SQL subqueries can be removed [^3]. But the (5), (6), and (7) rules are seldom used because the the query cost is increased as a result of the rules about common expression.<br \/>\nTake the following SQL statement as an example:<\/p>\n<pre><code>SELECT C_CUSTKEY\n\nFROM CUSTOMER WHERE 1000000 &lt;\n\n(SELECT SUM(O_TOTALPRICE)\n\nFROM ORDER WHERE O_CUSTKEY = C_CUSTKEY)\n<\/code><\/pre>\n<p>The two &#8220;CUSTKEY&#8221;s are the primary keys. When the statement is transformed to <code>Apply<\/code>, it is represented as:<\/p>\n<p>$$<br \/>\nsigma_{1000000&lt;X}(CUSTOMER A^times mathcal{G}^1_{X=SUM(O_PRICE)}(sigma_{O_CUSTKEY=C_CUSTKEY}ORDERS))<br \/>\n$$<\/p>\n<p>Because of the primary keys, according to rule (9), it can be transformed to the following:<\/p>\n<p>$$<br \/>\nsigma_{1000000&lt;X} mathcal{G}<em>{C_CUSTKEY,X = SUM(O_PRICE)}(CUSTOMER A^{LOJ} sigma<\/em>{O_CUSTKEY=C_CUSTKEY}ORDERS)<br \/>\n$$<\/p>\n<p><strong>Note:<\/strong><\/p>\n<ol>\n<li>If there are no primary keys in <code>ORDERS<\/code>, the $pi$ operator should be added to allocate a unique key.<\/li>\n<li>Pay attention to the difference between rule (8) and rule (9). For the $mathcal{G}^1_F$ aggregation function without the aggregation column, when the input is NULL, the output should be the default value of the <code>F<\/code> aggregation function. Therefore, the <code>LeftOuterJoin<\/code> should be used and a NULL record should be the output when the right table is NULL. In this case, based on rule (2), <code>Apply<\/code> can be completely removed. The statement can be transformed to a SQL statement with join:<\/li>\n<\/ol>\n<p>$$<br \/>\nsigma_{1000000&lt;X}mathcal{G}<em>{C_CUSTKEY,X=SUM(O_PRICE)}(CUSTOMER LOJ<\/em>{O_CUSTKEY=C_CUSTKEY}ORDERS)<br \/>\n$$<\/p>\n<p>Furthermore, based on the simplification of <code>OuterJoin<\/code>, the statement can be simplified to:<\/p>\n<p>$$<br \/>\nsigma_{1000000&lt;X}mathcal{G}<em>{C_CUSTKEY,X=SUM(O_PRICE)}(CUSTOMER Join<\/em>{O_CUSTKEY=C_CUSTKEY}ORDERS)<br \/>\n$$<\/p>\n<p>Theoretically, the above 9 rules have solved the correlation removal problem. But is correlation removal the best solution for all the scenarios? The answer is no. If the results of the SQL statement are small and the subquery can use the index, then the best solution is to use correlated execution. The <code>Apply<\/code> operator can be optimized to <code>Segment Apply<\/code>, which is to sort the data of the outer table according to the correlated key. In this case, the keys that are within one group won&#8217;t have to be executed multiple times. Of course, this is strongly related to the number of distinct values (NDV) of the correlated keys in the outer table. Therefore, the decision about whether to use correlation removal also depends on statistics. When it comes to this point, the regular optimizer is no longer applicable. Only the optimizer with the Volcano or Cascade Style can take both the logic equivalence rules and the cost-based optimization into consideration. Therefore, a perfect solution for subquery depends on an excellent optimizer framework.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Aggregation_and_subquery\"><\/span>Aggregation and subquery<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>In the previous section, the final statement is not completely optimized. The aggregation function above <code>OuterJoin<\/code> and <code>InnerJoin<\/code> can be pushed down[^4]. If <code>OutJoin<\/code> cannot be simplified, the formal representation of the push-down rule is:<\/p>\n<p>$$<br \/>\nmathcal{G_{A,F}}(S LOJ_p R)=pi_C(S LOJ_p(mathcal{G}_{A-attr(S),F}R))<br \/>\n$$<\/p>\n<p>The $pi_C$ above <code>Join<\/code> is to convert NULL to the default value when the aggregation function accepts empty values. It is worth mentioning that the above formula can be applied only when the following three conditions are met:<\/p>\n<ul>\n<li>All the columns that are related to <code>R<\/code> within the <code>p<\/code> predicate are in the <code>Group by<\/code> column.<\/li>\n<li>The key of the <code>S<\/code> relation is in the <code>Group by<\/code> column.<\/li>\n<li>The aggregations in the $mathcal{G}$ function only uses the columns in <code>R<\/code>.<\/li>\n<\/ul>\n<p>It is very common to use aggregation functions together with subqueries. The general solution is to use the formal representation of <code>Apply<\/code>, and remove the correlation based on the rules, then apply the push-down rules of the aggregation function for further optimization.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"References\"><\/span>References<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>[^1]: C. Galindo-Legaria and M. Joshi. &#8220;Orthogonal optimization of subqueries and aggregation&#8221;. In: <em>Proc. of the ACM SIGMOD Conf. on Management of Data (2001)<\/em>, pp. 571\u2013581.<\/p>\n<p>[^2]: D. Maier, Q. Wang and L. Shapiro. <em>Algebraic unnesting of nested object queries<\/em>. Tech. rep. CSE-99-013. Oregon Graduate Institute, 1999.<\/p>\n<p>[^3]: C. A. Galindo-Legaria. <em>Parameterized queries and nesting equivalences<\/em>. Tech. rep. MSR-TR-2000-31. Microsoft, 2001.<\/p>\n<p>[^4]: W. Yan and P.-A. Larson. &#8220;Eager aggregation and lazy aggregation&#8221;. In: <em>Proc. Int. Conf. on Very Large Data Bases (VLDB)<\/em> (1995), pp. 345\u2013357.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Subquery optimization, especially rewriting the correlated subquery, is a very difficult part in SQL query optimization. To be compatible with MySQL, TiDB enables users to write subqueries anywhere they want. For those subqueries that are not correlated, which are also called uncorrelated subqueries, TiDB evaluates in advance; for those correlated subqueries, TiDB removes the correlations as much as possible. For example, TiDB can rewrite a correlated subquery to `SemiJoin`. This article is focused on introducing the correlated subquery optimization methods in TiDB.<\/p>","protected":false},"author":114,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"ub_ctt_via":"","footnotes":""},"categories":[6],"tags":[7],"class_list":["post-1080","post","type-post","status-publish","format-standard","hentry","category-engineering","tag-query-execution"],"acf":[],"featured_image_src":null,"author_info":{"display_name":"Fei HAN","author_link":"https:\/\/www.pingcap.com\/ko\/blog\/author\/fei-han\/"},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.9 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Subquery Optimization in TiDB | TiDB<\/title>\n<meta name=\"description\" content=\"Learn about the benefits of TiDB and the TiDB Cloud solutions from PingCAP. Read our latest post &quot;Subquery Optimization in TiDB&quot; here.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.pingcap.com\/ko\/blog\/subquery-optimization-in-tidb\/\" \/>\n<meta property=\"og:locale\" content=\"ko_KR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Subquery Optimization in TiDB | TiDB\" \/>\n<meta property=\"og:description\" content=\"Learn about the benefits of TiDB and the TiDB Cloud solutions from PingCAP. Read our latest post &quot;Subquery Optimization in TiDB&quot; here.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.pingcap.com\/ko\/blog\/subquery-optimization-in-tidb\/\" \/>\n<meta property=\"og:site_name\" content=\"TiDB\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/facebook.com\/pingcap2015\" \/>\n<meta property=\"article:published_time\" content=\"2016-12-07T00:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-07-21T03:47:34+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/static.pingcap.com\/files\/2024\/09\/11005522\/Homepage-Ad.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1440\" \/>\n\t<meta property=\"og:image:height\" content=\"714\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Fei HAN\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@PingCAP\" \/>\n<meta name=\"twitter:site\" content=\"@PingCAP\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fei HAN\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7\ubd84\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.pingcap.com\/blog\/subquery-optimization-in-tidb\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.pingcap.com\/blog\/subquery-optimization-in-tidb\/\"},\"author\":{\"name\":\"Fei HAN\",\"@id\":\"https:\/\/www.pingcap.com\/#\/schema\/person\/bf97b4d9dcc1ae15522f8e0825e0b8f6\"},\"headline\":\"Subquery Optimization in TiDB\",\"datePublished\":\"2016-12-07T00:00:00+00:00\",\"dateModified\":\"2023-07-21T03:47:34+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.pingcap.com\/blog\/subquery-optimization-in-tidb\/\"},\"wordCount\":1315,\"publisher\":{\"@id\":\"https:\/\/www.pingcap.com\/#organization\"},\"keywords\":[\"Query execution\"],\"articleSection\":[\"Engineering\"],\"inLanguage\":\"ko-KR\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.pingcap.com\/blog\/subquery-optimization-in-tidb\/\",\"url\":\"https:\/\/www.pingcap.com\/blog\/subquery-optimization-in-tidb\/\",\"name\":\"Subquery Optimization in TiDB | TiDB\",\"isPartOf\":{\"@id\":\"https:\/\/www.pingcap.com\/#website\"},\"datePublished\":\"2016-12-07T00:00:00+00:00\",\"dateModified\":\"2023-07-21T03:47:34+00:00\",\"description\":\"Learn about the benefits of TiDB and the TiDB Cloud solutions from PingCAP. Read our latest post \\\"Subquery Optimization in TiDB\\\" here.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.pingcap.com\/blog\/subquery-optimization-in-tidb\/#breadcrumb\"},\"inLanguage\":\"ko-KR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.pingcap.com\/blog\/subquery-optimization-in-tidb\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.pingcap.com\/blog\/subquery-optimization-in-tidb\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.pingcap.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Subquery Optimization in TiDB\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.pingcap.com\/#website\",\"url\":\"https:\/\/www.pingcap.com\/\",\"name\":\"TiDB\",\"description\":\"TiDB | SQL at Scale\",\"publisher\":{\"@id\":\"https:\/\/www.pingcap.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.pingcap.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"ko-KR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.pingcap.com\/#organization\",\"name\":\"PingCAP\",\"url\":\"https:\/\/www.pingcap.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@id\":\"https:\/\/www.pingcap.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/static.pingcap.com\/files\/2021\/11\/pingcap-logo.png\",\"contentUrl\":\"https:\/\/static.pingcap.com\/files\/2021\/11\/pingcap-logo.png\",\"width\":811,\"height\":232,\"caption\":\"PingCAP\"},\"image\":{\"@id\":\"https:\/\/www.pingcap.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/facebook.com\/pingcap2015\",\"https:\/\/x.com\/PingCAP\",\"https:\/\/linkedin.com\/company\/pingcap\",\"https:\/\/youtube.com\/channel\/UCuq4puT32DzHKT5rU1IZpIA\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.pingcap.com\/#\/schema\/person\/bf97b4d9dcc1ae15522f8e0825e0b8f6\",\"name\":\"Fei HAN\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@id\":\"https:\/\/www.pingcap.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/static.pingcap.com\/files\/2022\/10\/17234942\/avatar.jpg\",\"contentUrl\":\"https:\/\/static.pingcap.com\/files\/2022\/10\/17234942\/avatar.jpg\",\"caption\":\"Fei HAN\"},\"url\":\"https:\/\/www.pingcap.com\/ko\/blog\/author\/fei-han\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Subquery Optimization in TiDB | TiDB","description":"Learn about the benefits of TiDB and the TiDB Cloud solutions from PingCAP. Read our latest post \"Subquery Optimization in TiDB\" here.","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:\/\/www.pingcap.com\/ko\/blog\/subquery-optimization-in-tidb\/","og_locale":"ko_KR","og_type":"article","og_title":"Subquery Optimization in TiDB | TiDB","og_description":"Learn about the benefits of TiDB and the TiDB Cloud solutions from PingCAP. Read our latest post \"Subquery Optimization in TiDB\" here.","og_url":"https:\/\/www.pingcap.com\/ko\/blog\/subquery-optimization-in-tidb\/","og_site_name":"TiDB","article_publisher":"https:\/\/facebook.com\/pingcap2015","article_published_time":"2016-12-07T00:00:00+00:00","article_modified_time":"2023-07-21T03:47:34+00:00","og_image":[{"width":1440,"height":714,"url":"https:\/\/static.pingcap.com\/files\/2024\/09\/11005522\/Homepage-Ad.png","type":"image\/png"}],"author":"Fei HAN","twitter_card":"summary_large_image","twitter_creator":"@PingCAP","twitter_site":"@PingCAP","twitter_misc":{"Written by":"Fei HAN","Est. reading time":"7\ubd84"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.pingcap.com\/blog\/subquery-optimization-in-tidb\/#article","isPartOf":{"@id":"https:\/\/www.pingcap.com\/blog\/subquery-optimization-in-tidb\/"},"author":{"name":"Fei HAN","@id":"https:\/\/www.pingcap.com\/#\/schema\/person\/bf97b4d9dcc1ae15522f8e0825e0b8f6"},"headline":"Subquery Optimization in TiDB","datePublished":"2016-12-07T00:00:00+00:00","dateModified":"2023-07-21T03:47:34+00:00","mainEntityOfPage":{"@id":"https:\/\/www.pingcap.com\/blog\/subquery-optimization-in-tidb\/"},"wordCount":1315,"publisher":{"@id":"https:\/\/www.pingcap.com\/#organization"},"keywords":["Query execution"],"articleSection":["Engineering"],"inLanguage":"ko-KR"},{"@type":"WebPage","@id":"https:\/\/www.pingcap.com\/blog\/subquery-optimization-in-tidb\/","url":"https:\/\/www.pingcap.com\/blog\/subquery-optimization-in-tidb\/","name":"Subquery Optimization in TiDB | TiDB","isPartOf":{"@id":"https:\/\/www.pingcap.com\/#website"},"datePublished":"2016-12-07T00:00:00+00:00","dateModified":"2023-07-21T03:47:34+00:00","description":"Learn about the benefits of TiDB and the TiDB Cloud solutions from PingCAP. Read our latest post \"Subquery Optimization in TiDB\" here.","breadcrumb":{"@id":"https:\/\/www.pingcap.com\/blog\/subquery-optimization-in-tidb\/#breadcrumb"},"inLanguage":"ko-KR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.pingcap.com\/blog\/subquery-optimization-in-tidb\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.pingcap.com\/blog\/subquery-optimization-in-tidb\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.pingcap.com\/"},{"@type":"ListItem","position":2,"name":"Subquery Optimization in TiDB"}]},{"@type":"WebSite","@id":"https:\/\/www.pingcap.com\/#website","url":"https:\/\/www.pingcap.com\/","name":"\ud2f0DB","description":"TiDB | SQL at Scale","publisher":{"@id":"https:\/\/www.pingcap.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.pingcap.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"ko-KR"},{"@type":"Organization","@id":"https:\/\/www.pingcap.com\/#organization","name":"PingCAP","url":"https:\/\/www.pingcap.com\/","logo":{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/www.pingcap.com\/#\/schema\/logo\/image\/","url":"https:\/\/static.pingcap.com\/files\/2021\/11\/pingcap-logo.png","contentUrl":"https:\/\/static.pingcap.com\/files\/2021\/11\/pingcap-logo.png","width":811,"height":232,"caption":"PingCAP"},"image":{"@id":"https:\/\/www.pingcap.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/facebook.com\/pingcap2015","https:\/\/x.com\/PingCAP","https:\/\/linkedin.com\/company\/pingcap","https:\/\/youtube.com\/channel\/UCuq4puT32DzHKT5rU1IZpIA"]},{"@type":"Person","@id":"https:\/\/www.pingcap.com\/#\/schema\/person\/bf97b4d9dcc1ae15522f8e0825e0b8f6","name":"Fei HAN","image":{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/www.pingcap.com\/#\/schema\/person\/image\/","url":"https:\/\/static.pingcap.com\/files\/2022\/10\/17234942\/avatar.jpg","contentUrl":"https:\/\/static.pingcap.com\/files\/2022\/10\/17234942\/avatar.jpg","caption":"Fei HAN"},"url":"https:\/\/www.pingcap.com\/ko\/blog\/author\/fei-han\/"}]}},"grav_blocks":false,"card_markup":"<a class=\"card-resource bg-white\" href=\"https:\/\/www.pingcap.com\/ko\/blog\/subquery-optimization-in-tidb\/\"><div class=\"card-resource__content-container\"><div class=\"card-resource__content-head\"><div class=\"card-resource__category\">Engineering<\/div><\/div><h5 class=\"card-resource__title\">Subquery Optimization in TiDB<\/h5><\/div><\/a>","_links":{"self":[{"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/posts\/1080","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/users\/114"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/comments?post=1080"}],"version-history":[{"count":2,"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/posts\/1080\/revisions"}],"predecessor-version":[{"id":13054,"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/posts\/1080\/revisions\/13054"}],"wp:attachment":[{"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/media?parent=1080"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/categories?post=1080"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/tags?post=1080"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}