blob: 92ca703e3284637310fe107a52bdb7bf9fe91595 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-61232409-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-61232409-1');
</script>
<!-- Yandex.Metrika counter -->
<script type="text/javascript" >
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
ym(72949126, "init", {
clickmap:true,
trackLinks:true,
accurateTrackBounce:true,
webvisor:true
});
</script>
<noscript><div><img src="https://mc.yandex.ru/watch/72949126" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
<!-- /Yandex.Metrika counter -->
<!-- Bugyard widget embed -->
<script type="text/javascript">!function(){if("function"!=typeof window.bugyard){var a=function(){a.c(arguments)};a.q=[],a.c=function(b){a.q.push(b)},window.bugyard=a;var b=document.createElement("script");b.setAttribute("data-bugyard","610961912c35ff001493163a"),b.setAttribute("async","async"),b.setAttribute("defer","defer"),b.setAttribute("src","https://widget.bugyard.io/bugyard.min.js"),document.getElementsByTagName("head")[0].appendChild(b)}}(); window.bugyard("hideButton"); </script>
<link rel="preload" href='/assets/js/code-tabs.js?1' as="script" crossorigin>
<link rel="preload" href='/assets/js/page-nav.js' as="script" crossorigin>
<link rel="preload" href='/assets/js/docs-menu.js?20201005' as="script" crossorigin>
<style>:root{--gg-red:#ec1c24;--gg-orange:#ec1c24;--gg-orange-dark:#bc440b;--gg-orange-filter:invert(47%) sepia(61%) saturate(1950%) hue-rotate(345deg) brightness(100%) contrast(95%);--gg-dark-gray:#333333;--orange-line-thickness:3px;--block-code-background:rgba(241, 241, 241, 20%);--inline-code-background:rgba(241, 241, 241, 90%);--padding-top:25px;--link-color:#ec1c24;--body-background:#fcfcfc}header{min-height:var(--header-height);background:#fff;box-shadow:0 4px 10px 0 #eee,0 0 4px 0 #d5d5d5;z-index:1}header>.container{display:grid;grid-template-columns:auto auto 1fr auto auto auto;grid-template-areas:'left-toggle home nav ver api search lang';grid-template-rows:40px;flex-direction:row;align-items:center;justify-content:flex-start;padding:12px 20px;max-width:1400px;margin:0 auto}header nav>ul{padding:0;margin:0;list-style:none;display:inherit}header .dropdown{display:none;position:fixed;top:calc(var(--header-height) - 12px);width:auto;background:#fff;box-shadow:0 4px 4px 0 rgba(0,0,0,.24),0 0 4px 0 rgba(0,0,0,.12);border-radius:4px;padding-top:10px;padding-bottom:12px;z-index:2}header .dropdown li{display:flex}header .dropdown a{color:grey!important;font-size:16px;padding-top:5px;padding-bottom:4px}header .menu{border:none;background:0 0;width:40px;height:40px;margin-right:12px;grid-area:left-toggle}header .menu img{width:18px;height:12px}header .search-close,header .top-nav-toggle{background:0 0;border:none;padding:0;width:36px;height:36px;display:inline-flex;align-items:center;justify-content:center;color:var(--gg-dark-gray);font-size:26px}header .search-toggle{grid-area:search}header .top-nav-toggle{grid-area:top-toggle}header .home{grid-area:home;margin-right:auto}header .home img{height:36px}header #api-docs{grid-area:api;margin:0;display:flex}header #api-docs .dropdown{padding:.5em 0}header #api-docs a{padding:9px 14px;color:var(--gg-dark-gray)!important;text-decoration:none;white-space:nowrap}header #api-docs .dropdown-item a{font-weight:400;display:block;width:100%;min-width:150px}header #lang-selector li{list-style:none;display:flex;padding:9px 14px}header #lang-selector li a{display:flex;color:#000;align-items:center}header #lang-selector li a span{font-size:10px;margin-left:5px}header #lang-selector li a img{width:25px}header #lang-selector li .dropdown{margin-left:-70px}header #lang-selector li .dropdown .dropdown-item{padding:0 1em;margin-bottom:8px}header #lang-selector li .dropdown .dropdown-item a span{font-size:14px}header .search{margin-left:auto;margin-right:20px;grid-area:search}header .search input[type=search]{color:var(--gg-dark-gray);background:rgba(255,255,255,.8);border:1px solid #ccc;padding:10px 15px;font-family:inherit;max-width:148px;height:37px;font-size:14px;-webkit-appearance:unset;appearance:unset}header #version-selector{list-style:none;grid-area:ver;line-height:28px;border-radius:0;margin-right:10px;border:none;color:var(--gg-dark-gray);padding:5px 16px 5px 10px;white-space:nowrap;font-size:14px;width:auto;text-align:right;box-sizing:border-box;text-align-last:right;-moz-appearance:none;-webkit-appearance:none;appearance:none;direction:rtl}header #version-selector option{direction:ltr}header>nav{grid-area:nav;font-size:18px;display:flex;flex-direction:row;margin:0 20px}header #lang-selector{grid-area:lang}header .search-close{margin-right:10px}@media (max-width:600px){header .search{margin-right:5px}header .search input[type=search]{max-width:110px}}header:not(.narrow-header) .search-close,header:not(.narrow-header) .top-nav-toggle{display:none}@media (max-width:670px){header>.container{grid-template-columns:auto 1fr auto;grid-template-areas:'left-toggle home search' 'ver api lang'}header #lang-selector li{justify-content:flex-end}}pre,pre.rouge{padding:8px 15px;background:var(--block-code-background)!important;border-radius:5px;border:1px solid #e5e5e5;overflow-x:auto;min-height:36px;line-height:18px;color:#545454}code{color:#545454}pre.rouge code{background:0 0!important}:not(pre)>code{background:var(--inline-code-background);padding:.1em .5em;background-clip:padding-box;border-radius:3px;color:#545454;font-size:90%}.listingblock .content{position:relative}.highlight{color:#586e75}.highlight .c1{color:#657b83}.highlight .nt{color:#b58900}.highlight .o{color:#93a1a1}.highlight .k{color:#6c71c4}.highlight .kt{color:#cb4b16}.highlight .s,.highlight .s1{color:#859900}.highlight .nc{color:#b58900}.highlight .na{color:#268bd2}body{font-family:'Open Sans',sans-serif}h1,h2{color:#000;font-weight:400;font-family:'Open Sans'}h1{font-size:36px;line-height:40px}a{text-decoration:none;color:var(--link-color)}section{color:#545454}.admonitionblock .icon .title{display:none}body{--header-height:64px;--promotion-bar-height:35px;--footer-height:104px;--footer-gap:60px;padding:0;margin:0;display:flex;flex-direction:column;min-height:100vh;background-color:var(--body-background);font-family:'Open Sans',sans-serif}body>section{flex:1}header{position:-webkit-sticky;position:sticky;top:0;z-index:2}*{box-sizing:border-box}@media (max-width:670px){body{--header-height:97px}}.left-nav{padding:10px 20px;width:289px;overflow-y:auto;top:calc(var(--header-height) + var(--promotion-bar-height));height:calc(100vh - var(--header-height) - var(--promotion-bar-height));font-family:'Open Sans';padding-top:var(--padding-top);background-color:var(--body-background)}.left-nav li{list-style:none}.left-nav a,.left-nav button{text-decoration:none;color:#757575;font-size:16px;display:inline-flex;width:100%;margin:2px 0;padding:.25em .375em;background:0 0;border:none;font:inherit;text-align:left}.left-nav a.active{color:var(--link-color)}.left-nav .nav-group{margin-left:6px;font-size:14px}.left-nav nav{border-left:2px solid #ddd;margin-bottom:5px}.left-nav nav.collapsed{display:none}.left-nav nav>li>a,.left-nav nav>li>button{padding-left:20px;text-align:left}.left-nav nav>li>a.active{border-left:var(--orange-line-thickness) solid var(--active-color);padding-left:calc(20px - var(--orange-line-thickness))}.left-nav nav.sub_pages{border:none}.left-nav nav.sub_pages a{padding-left:32px}.left-nav .state-indicator{margin-left:auto;margin-top:5px;width:6.2px;height:10px;flex:0 0 auto;filter:invert(49%) sepia(4%) saturate(5%) hue-rotate(23deg) brightness(92%) contrast(90%)}.left-nav button.expanded .state-indicator{transform:rotate(90deg)}.right-nav{width:289px;padding:12px 26px;overflow-y:auto;height:calc(100vh - var(--header-height));top:0;position:-webkit-sticky;position:sticky;display:flex;flex-direction:column;font-family:'Open sans';padding-top:var(--padding-top);background-color:#fff}.right-nav ul{list-style:none;padding:0;margin:0}.right-nav li{padding:0}.right-nav a{--border-width:0px;font-size:14px;color:#757575;padding-left:calc(15px * var(--nesting-level) + 8px - var(--border-width));margin:.3em 0;display:inline-block}.right-nav .sectlevel1{border-left:2px solid #ddd}.right-nav .sectlevel1{--nesting-level:0}.right-nav .sectlevel2{--nesting-level:1}.right-nav .sectlevel3{--nesting-level:2}@media (max-width:1200px){.right-nav{width:230px}}.right-nav footer{font-size:12px;padding:calc(var(--footer-gap) * .3) 0 5px;text-align:left;margin:auto 0 0}section.page-docs{display:grid;grid-template-columns:auto 1fr auto;grid-template-rows:100%;grid-template-areas:'left-nav content right-nav';line-height:20px;max-width:1440px;margin:auto;width:100%}section.page-docs>article{border-left:1px solid #eee;background-color:#fff;padding:0 50px 30px;grid-area:content;overflow:hidden;font-family:sans-serif;font-size:16px;color:#545454;line-height:1.6em}section.page-docs>article h1,section.page-docs>article h2{font-family:'Open Sans'}@media (max-width:800px){section.page-docs>article{padding-left:15px;padding-right:15px}}section.page-docs .edit-link{position:relative;top:10px;right:10px;float:right;padding-top:calc(var(--header-height) + var(--padding-top));margin-top:calc((-1 * var(--header-height)))}section.page-docs h1,section.page-docs h2{margin-bottom:0}section.page-docs h2[id]{margin-top:var(--margin-top);margin-bottom:calc(var(--margin-top) * .5);z-index:-1}section.page-docs .title{font-style:italic}section.page-docs h2[id]{--margin-top:1.2em}.left-nav{bottom:0;position:-webkit-sticky;position:sticky}.left-nav{grid-area:left-nav}.right-nav{grid-area:right-nav}.left-nav__overlay{display:none;background:rgba(0,0,0,.5);z-index:1;position:fixed;top:var(--header-height);bottom:0;left:0;right:0}@media (max-width:990px){body:not(.hide-left-nav) .left-nav__overlay{display:block}nav.left-nav{background:#fafafa;grid-area:left-nav;box-shadow:0 4px 4px 0 rgba(0,0,0,.24),0 0 4px 0 rgba(0,0,0,.12);min-height:calc(100vh - var(--header-height));max-height:calc(100vh - var(--header-height));position:fixed;bottom:0;top:var(--header-height);z-index:2}section.page-docs>article{grid-column-start:left-nav;grid-column-end:content;grid-row:content}}@media (max-width:800px){nav.right-nav{display:none}}:target:before{content:"";display:block;margin-top:calc(var(--header-height) * -1);height:var(--header-height);width:1px}@media (min-width:600px) and (max-width:900px){:target:before{content:"";display:block;width:1px;margin-top:-150px;height:150px}}
#header #promotion-bar { background-color: #333333; padding: 8px; }
#header #promotion-bar p { font-size: 14px; line-height: 1.4em; font-weight: 600; padding: 0; margin: 0; color: #f0f0f0; text-align: center;}
#header #promotion-bar p a { color: #FCB903; } </style>
<meta name="ignite-version" content="2.9.1" />
<title>SQL Performance Tuning | Ignite Documentation</title>
<link rel="canonical" href="/docs/2.9.1/perf-and-troubleshooting/sql-tuning" />
<META NAME="ROBOTS" CONTENT="NOINDEX" />
<link rel="shortcut icon" href="/favicon.ico">
<meta name='viewport' content='width=device-width, height=device-height, initial-scale=1.0, minimum-scale=1.0'>
<link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;600;700&display=swap" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;600;700&display=swap" media="print" onload="this.media='all'">
<noscript>
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;600;700&display=swap" rel="stylesheet">
</noscript>
<script>
// AnchorJS - v4.2.0 - 2019-01-01
// https://github.com/bryanbraun/anchorjs
// Copyright (c) 2019 Bryan Braun; Licensed MIT
!function(A,e){"use strict";"function"==typeof define&&define.amd?define([],e):"object"==typeof module&&module.exports?module.exports=e():(A.AnchorJS=e(),A.anchors=new A.AnchorJS)}(this,function(){"use strict";return function(A){function f(A){A.icon=A.hasOwnProperty("icon")?A.icon:"",A.visible=A.hasOwnProperty("visible")?A.visible:"hover",A.placement=A.hasOwnProperty("placement")?A.placement:"right",A.ariaLabel=A.hasOwnProperty("ariaLabel")?A.ariaLabel:"Anchor",A.class=A.hasOwnProperty("class")?A.class:"",A.base=A.hasOwnProperty("base")?A.base:"",A.truncate=A.hasOwnProperty("truncate")?Math.floor(A.truncate):64,A.titleText=A.hasOwnProperty("titleText")?A.titleText:""}function p(A){var e;if("string"==typeof A||A instanceof String)e=[].slice.call(document.querySelectorAll(A));else{if(!(Array.isArray(A)||A instanceof NodeList))throw new Error("The selector provided to AnchorJS was invalid.");e=[].slice.call(A)}return e}this.options=A||{},this.elements=[],f(this.options),this.isTouchDevice=function(){return!!("ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch)},this.add=function(A){var e,t,i,n,o,s,a,r,c,h,l,u,d=[];if(f(this.options),"touch"===(l=this.options.visible)&&(l=this.isTouchDevice()?"always":"hover"),A||(A="h2, h3, h4, h5, h6"),0===(e=p(A)).length)return this;for(function(){if(null===document.head.querySelector("style.anchorjs")){var A,e=document.createElement("style");e.className="anchorjs",e.appendChild(document.createTextNode("")),void 0===(A=document.head.querySelector('[rel="stylesheet"], style'))?document.head.appendChild(e):document.head.insertBefore(e,A),e.sheet.insertRule(" .anchorjs-link { opacity: 0; text-decoration: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }",e.sheet.cssRules.length),e.sheet.insertRule(" *:hover > .anchorjs-link, .anchorjs-link:focus { opacity: 1; }",e.sheet.cssRules.length),e.sheet.insertRule(" [data-anchorjs-icon]::after { content: attr(data-anchorjs-icon); }",e.sheet.cssRules.length),e.sheet.insertRule(' @font-face { font-family: "anchorjs-icons"; src: url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype"); }',e.sheet.cssRules.length)}}(),t=document.querySelectorAll("[id]"),i=[].map.call(t,function(A){return A.id}),o=0;o<e.length;o++)if(this.hasAnchorJSLink(e[o]))d.push(o);else{if(e[o].hasAttribute("id"))n=e[o].getAttribute("id");else if(e[o].hasAttribute("data-anchor-id"))n=e[o].getAttribute("data-anchor-id");else{for(c=r=this.urlify(e[o].textContent),a=0;void 0!==s&&(c=r+"-"+a),a+=1,-1!==(s=i.indexOf(c)););s=void 0,i.push(c),e[o].setAttribute("id",c),n=c}n.replace(/-/g," "),(h=document.createElement("a")).className="anchorjs-link "+this.options.class,h.setAttribute("aria-label",this.options.ariaLabel),h.setAttribute("data-anchorjs-icon",this.options.icon),this.options.titleText&&(h.title=this.options.titleText),u=document.querySelector("base")?window.location.pathname+window.location.search:"",u=this.options.base||u,h.href=u+"#"+n,"always"===l&&(h.style.opacity="1"),""===this.options.icon&&(h.style.font="1em/1 anchorjs-icons","left"===this.options.placement&&(h.style.lineHeight="inherit")),"left"===this.options.placement?(h.style.position="absolute",h.style.marginLeft="-1em",h.style.paddingRight="0.5em",e[o].insertBefore(h,e[o].firstChild)):(h.style.paddingLeft="0.375em",e[o].appendChild(h))}for(o=0;o<d.length;o++)e.splice(d[o]-o,1);return this.elements=this.elements.concat(e),this},this.remove=function(A){for(var e,t,i=p(A),n=0;n<i.length;n++)(t=i[n].querySelector(".anchorjs-link"))&&(-1!==(e=this.elements.indexOf(i[n]))&&this.elements.splice(e,1),i[n].removeChild(t));return this},this.removeAll=function(){this.remove(this.elements)},this.urlify=function(A){return this.options.truncate||f(this.options),A.trim().replace(/\'/gi,"").replace(/[& +$,:;=?@"#{}|^~[`%!'<>\]\.\/\(\)\*\\\n\t\b\v]/g,"-").replace(/-{2,}/g,"-").substring(0,this.options.truncate).replace(/^-+|-+$/gm,"").toLowerCase()},this.hasAnchorJSLink=function(A){var e=A.firstChild&&-1<(" "+A.firstChild.className+" ").indexOf(" anchorjs-link "),t=A.lastChild&&-1<(" "+A.lastChild.className+" ").indexOf(" anchorjs-link ");return e||t||!1}}});
</script>
</head>
<body>
<header>
<!--#include virtual="/includes/promotion_banner.html" -->
<div class="container">
<button type='button' class='menu' title='Docs menu'>
<img src="/assets/images/menu-icon.svg" width="18" height="12" alt="menu icon" />
</button>
<div class='home'>
<a href="/" class='home' title='Apache Ignite home'>
<img src="/assets/images/apache_ignite_logo.svg" alt="Apache Ignite logo" width="103" height="36" >
</a>
</div>
<select id="version-selector">
<option value="2.9.1">2.9.1</option>
</select>
<nav id="api-docs"><ul>
<li><a href="#">APIs</a>
<nav class='dropdown'>
<ul>
<li class="dropdown-item"><a href="/releases/latest/javadoc/index.html">Java</a></li>
<li class="dropdown-item"><a href="/releases/latest/dotnetdoc/api/">C#/.NET</a></li>
<li class="dropdown-item"><a href="/releases/latest/cppdoc/index.html">C++</a></li>
<li class="dropdown-item"><a href="/releases/latest/scaladoc/scalar/index.html#org.apache.ignite.scalar.scalar$">Scala</a></li>
</ul>
</nav>
</li>
<li><a href="#">Examples</a>
<nav class="dropdown">
<ul>
<li class="dropdown-item"><a href="https://github.com/apache/ignite/tree/master/examples" target="_blank" rel="noopener" title="Apache Ignite Java examples">Java</a></li>
<li class="dropdown-item"><a href="https://github.com/apache/ignite/tree/master/modules/platforms/dotnet/examples" target="_blank" rel="noopener" title="Apache Ignite C#/.NET examples">C#/.NET</a></li>
<li class="dropdown-item"><a href="https://github.com/apache/ignite/tree/master/modules/platforms/cpp/examples" target="_blank" rel="noopener" title="Apache Ignite C++ examples">C++</a></li>
<li class="dropdown-item"><a href="https://github.com/apache/ignite/tree/master/modules/platforms/python/examples" target="_blank" rel="noopener" title="Apache Ignite Python examples">Python</a></li>
<li class="dropdown-item"><a href="https://github.com/apache/ignite/tree/master/modules/platforms/nodejs/examples" target="_blank" rel="noopener" title="Apache Ignite NodeJS examples">NodeJS</a></li>
<li class="dropdown-item"><a href="https://github.com/apache/ignite/tree/master/modules/platforms/php/examples" target="_blank" rel="noopener" title="Apache Ignite PHP examples">PHP</a></li>
</ul>
</nav>
</li></ul>
</nav>
<form class='search'>
<button class="search-close" type='button'><img src='/assets/images/cancel.svg' alt="close" width="10" height="10" /></button>
<input type="search" placeholder="Search…" id="search-input">
</form>
<nav id="lang-selector"><ul>
<li><a href="#"><img src="/assets/images/icon_lang_en_75x75.jpg" alt="English language icon" width="25" height="25" /><span></span></a>
<nav class="dropdown">
<li class="dropdown-item"><a href="/docs/latest/" ><img src="/assets/images/icon_lang_en_75x75.jpg" alt="English language icon" width="25" height="25" /><span>English</span></a></li>
<li class="dropdown-item"><a href="https://www.ignite-service.cn/doc/java/" target="_blank" rel="noopener"><img src="/assets/images/icon_lang_cn_75x75.jpg" width="25" height="25" alt="Chinese language icon" /><span>Chinese</span></a></li>
</nav>
</li></ul>
</nav>
<button type='button' class='top-nav-toggle'></button>
</div>
</header>
<link rel="stylesheet" href="/assets/css/docs.css">
<section class='page-docs'>
<nav class='left-nav' data-swiftype-index='false'>
<li>
<a href="/docs/2.9.1/index" class='' >Documentation Overview</a>
</li>
<li>
<button type='button' class='group-toggle collapsed '>Quick Start Guides<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class='nav-group collapsed'>
<li>
<a href="/docs/2.9.1/quick-start/java"
class=''
>Java</a>
</li>
<li>
<a href="/docs/2.9.1/quick-start/dotnet"
class=''
>.NET/C#</a>
</li>
<li>
<a href="/docs/2.9.1/quick-start/cpp"
class=''
>C++</a>
</li>
<li>
<a href="/docs/2.9.1/quick-start/python"
class=''
>Python</a>
</li>
<li>
<a href="/docs/2.9.1/quick-start/nodejs"
class=''
>Node.JS</a>
</li>
<li>
<a href="/docs/2.9.1/quick-start/sql"
class=''
>SQL</a>
</li>
<li>
<a href="/docs/2.9.1/quick-start/php"
class=''
>PHP</a>
</li>
<li>
<a href="/docs/2.9.1/quick-start/restapi"
class=''
>REST API</a>
</li>
</nav>
</li>
<li>
<button type='button' class='group-toggle collapsed '>Installation<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class='nav-group collapsed'>
<li>
<a href="/docs/2.9.1/installation/installing-using-zip"
class=''
>Installing Using ZIP Archive</a>
</li>
<li>
<a href="/docs/2.9.1/installation/installing-using-docker"
class=''
>Installing Using Docker</a>
</li>
<li>
<a href="/docs/2.9.1/installation/deb-rpm"
class=''
>Installing DEB or RPM package</a>
</li>
<li>
<button
type='button'
class='collapsed '>Kubernetes<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class="sub_pages collapsed">
<li><a href="/docs/2.9.1/installation/kubernetes/amazon-eks-deployment" class=''>Amazon EKS</a></li>
<li><a href="/docs/2.9.1/installation/kubernetes/azure-deployment" class=''>Azure Kubernetes Service</a></li>
<li><a href="/docs/2.9.1/installation/kubernetes/gke-deployment" class=''>Google Kubernetes Engine</a></li>
</nav>
</li>
<li>
<a href="/docs/2.9.1/installation/vmware-installation"
class=''
>VMWare</a>
</li>
</nav>
</li>
<li>
<button type='button' class='group-toggle collapsed '>Setting Up<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class='nav-group collapsed'>
<li>
<a href="/docs/2.9.1/understanding-configuration"
class=''
>Understanding Configuration</a>
</li>
<li>
<a href="/docs/2.9.1/setup"
class=''
>Setting Up</a>
</li>
<li>
<a href="/docs/2.9.1/logging"
class=''
>Configuring Logging</a>
</li>
<li>
<a href="/docs/2.9.1/resources-injection"
class=''
>Resources Injection</a>
</li>
</nav>
</li>
<li>
<a href="/docs/2.9.1/starting-nodes" class='' >Starting and Stopping Nodes</a>
</li>
<li>
<button type='button' class='group-toggle collapsed '>Clustering<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class='nav-group collapsed'>
<li>
<a href="/docs/2.9.1/clustering/clustering"
class=''
>Overview</a>
</li>
<li>
<a href="/docs/2.9.1/clustering/tcp-ip-discovery"
class=''
>TCP/IP Discovery</a>
</li>
<li>
<a href="/docs/2.9.1/clustering/zookeeper-discovery"
class=''
>ZooKeeper Discovery</a>
</li>
<li>
<a href="/docs/2.9.1/clustering/discovery-in-the-cloud"
class=''
>Discovery in the Cloud</a>
</li>
<li>
<a href="/docs/2.9.1/clustering/network-configuration"
class=''
>Network Configuration</a>
</li>
<li>
<a href="/docs/2.9.1/clustering/connect-client-nodes"
class=''
>Connecting Client Nodes</a>
</li>
<li>
<a href="/docs/2.9.1/clustering/baseline-topology"
class=''
>Baseline Topology</a>
</li>
<li>
<a href="/docs/2.9.1/clustering/running-client-nodes-behind-nat"
class=''
>Running Client Nodes Behind NAT</a>
</li>
</nav>
</li>
<li>
<button type='button' class='group-toggle collapsed '>Thin Clients<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class='nav-group collapsed'>
<li>
<a href="/docs/2.9.1/thin-clients/getting-started-with-thin-clients"
class=''
>Thin Clients Overview</a>
</li>
<li>
<a href="/docs/2.9.1/thin-clients/java-thin-client"
class=''
>Java Thin Client</a>
</li>
<li>
<a href="/docs/2.9.1/thin-clients/dotnet-thin-client"
class=''
>.NET Thin Client</a>
</li>
<li>
<a href="/docs/2.9.1/thin-clients/cpp-thin-client"
class=''
>C++ Thin Client</a>
</li>
<li>
<a href="/docs/2.9.1/thin-clients/python-thin-client"
class=''
>Python Thin Client</a>
</li>
<li>
<a href="/docs/2.9.1/thin-clients/php-thin-client"
class=''
>PHP Thin Client</a>
</li>
<li>
<a href="/docs/2.9.1/thin-clients/nodejs-thin-client"
class=''
>Node.js Thin Client</a>
</li>
<li>
<button
type='button'
class='collapsed '>Binary Client Protocol<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class="sub_pages collapsed">
<li><a href="/docs/2.9.1/binary-client-protocol/binary-client-protocol" class=''>Binary Client Protocol</a></li>
<li><a href="/docs/2.9.1/binary-client-protocol/data-format" class=''>Data Format</a></li>
<li><a href="/docs/2.9.1/binary-client-protocol/key-value-queries" class=''>Key-Value Queries</a></li>
<li><a href="/docs/2.9.1/binary-client-protocol/sql-and-scan-queries" class=''>SQL and Scan Queries</a></li>
<li><a href="/docs/2.9.1/binary-client-protocol/binary-type-metadata" class=''>Binary Types Metadata</a></li>
<li><a href="/docs/2.9.1/binary-client-protocol/cache-configuration" class=''>Cache Configuration</a></li>
</nav>
</li>
</nav>
</li>
<li>
<button type='button' class='group-toggle collapsed '>Data Modeling<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class='nav-group collapsed'>
<li>
<a href="/docs/2.9.1/data-modeling/data-modeling"
class=''
>Introduction</a>
</li>
<li>
<a href="/docs/2.9.1/data-modeling/data-partitioning"
class=''
>Data Partitioning</a>
</li>
<li>
<a href="/docs/2.9.1/data-modeling/affinity-collocation"
class=''
>Affinity Colocation</a>
</li>
<li>
<a href="/docs/2.9.1/data-modeling/binary-marshaller"
class=''
>Binary Marshaller</a>
</li>
</nav>
</li>
<li>
<button type='button' class='group-toggle collapsed '>Configuring Memory<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class='nav-group collapsed'>
<li>
<a href="/docs/2.9.1/memory-architecture"
class=''
>Memory Architecture</a>
</li>
<li>
<a href="/docs/2.9.1/memory-configuration/data-regions"
class=''
>Configuring Data Regions</a>
</li>
<li>
<a href="/docs/2.9.1/memory-configuration/eviction-policies"
class=''
>Eviction Policies</a>
</li>
<li>
<a href="/docs/2.9.1/memory-configuration/replacement-policies"
class=''
>Replacement Policies</a>
</li>
</nav>
</li>
<li>
<button type='button' class='group-toggle collapsed '>Configuring Persistence<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class='nav-group collapsed'>
<li>
<a href="/docs/2.9.1/persistence/native-persistence"
class=''
>Ignite Persistence</a>
</li>
<li>
<a href="/docs/2.9.1/persistence/external-storage"
class=''
>External Storage</a>
</li>
<li>
<a href="/docs/2.9.1/persistence/swap"
class=''
>Swapping</a>
</li>
<li>
<a href="/docs/2.9.1/persistence/custom-cache-store"
class=''
>Implementing Custom Cache Store</a>
</li>
<li>
<a href="/docs/2.9.1/persistence/snapshot-directory"
class=''
>Configuring Snapshot Directory</a>
</li>
<li>
<a href="/docs/2.9.1/persistence/disk-compression"
class=''
>Disk Compression</a>
</li>
<li>
<a href="/docs/2.9.1/persistence/persistence-tuning"
class=''
>Tuning Persistence</a>
</li>
</nav>
</li>
<li>
<a href="/docs/2.9.1/snapshots/snapshots" class='' >Cluster Snapshots</a>
</li>
<li>
<button type='button' class='group-toggle collapsed '>Configuring Caches<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class='nav-group collapsed'>
<li>
<a href="/docs/2.9.1/configuring-caches/configuration-overview"
class=''
>Cache Configuration</a>
</li>
<li>
<a href="/docs/2.9.1/configuring-caches/configuring-backups"
class=''
>Configuring Partition Backups</a>
</li>
<li>
<a href="/docs/2.9.1/configuring-caches/partition-loss-policy"
class=''
>Partition Loss Policy</a>
</li>
<li>
<a href="/docs/2.9.1/configuring-caches/atomicity-modes"
class=''
>Atomicity Modes</a>
</li>
<li>
<a href="/docs/2.9.1/configuring-caches/expiry-policies"
class=''
>Expiry Policy</a>
</li>
<li>
<a href="/docs/2.9.1/configuring-caches/on-heap-caching"
class=''
>On-Heap Caching</a>
</li>
<li>
<a href="/docs/2.9.1/configuring-caches/cache-groups"
class=''
>Cache Groups</a>
</li>
<li>
<a href="/docs/2.9.1/configuring-caches/near-cache"
class=''
>Near Caches</a>
</li>
</nav>
</li>
<li>
<a href="/docs/2.9.1/data-rebalancing" class='' >Data Rebalancing</a>
</li>
<li>
<a href="/docs/2.9.1/data-streaming" class='' >Data Streaming</a>
</li>
<li>
<button type='button' class='group-toggle collapsed '>Using Key-Value API<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class='nav-group collapsed'>
<li>
<a href="/docs/2.9.1/key-value-api/basic-cache-operations"
class=''
>Basic Cache Operations</a>
</li>
<li>
<a href="/docs/2.9.1/key-value-api/binary-objects"
class=''
>Working with Binary Objects</a>
</li>
<li>
<a href="/docs/2.9.1/key-value-api/using-cache-queries"
class=''
>Using Cache Queries</a>
</li>
<li>
<a href="/docs/2.9.1/read-repair"
class=''
>Read Repair</a>
</li>
</nav>
</li>
<li>
<a href="/docs/2.9.1/key-value-api/transactions" class='' >Performing Transactions</a>
</li>
<li>
<button type='button' class='group-toggle collapsed '>Working with SQL<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class='nav-group collapsed'>
<li>
<a href="/docs/2.9.1/SQL/sql-introduction"
class=''
>Introduction</a>
</li>
<li>
<a href="/docs/2.9.1/SQL/schemas"
class=''
>Understanding Schemas</a>
</li>
<li>
<a href="/docs/2.9.1/SQL/indexes"
class=''
>Defining Indexes</a>
</li>
<li>
<a href="/docs/2.9.1/SQL/sql-api"
class=''
>Using SQL API</a>
</li>
<li>
<a href="/docs/2.9.1/SQL/distributed-joins"
class=''
>Distributed Joins</a>
</li>
<li>
<a href="/docs/2.9.1/SQL/custom-sql-func"
class=''
>Custom SQL Functions</a>
</li>
<li>
<a href="/docs/2.9.1/SQL/JDBC/jdbc-driver"
class=''
>JDBC Driver</a>
</li>
<li>
<a href="/docs/2.9.1/SQL/JDBC/jdbc-client-driver"
class=''
>JDBC Client Driver</a>
</li>
<li>
<button
type='button'
class='collapsed '>ODBC Driver<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class="sub_pages collapsed">
<li><a href="/docs/2.9.1/SQL/ODBC/odbc-driver" class=''>ODBC Driver</a></li>
<li><a href="/docs/2.9.1//SQL/ODBC/connection-string-dsn" class=''>Connection String and DSN</a></li>
<li><a href="/docs/2.9.1/SQL/ODBC/querying-modifying-data" class=''>Querying and Modifying Data</a></li>
<li><a href="/docs/2.9.1/SQL/ODBC/specification" class=''>Specification</a></li>
<li><a href="/docs/2.9.1/SQL/ODBC/data-types" class=''>Data Types</a></li>
<li><a href="/docs/2.9.1/SQL/ODBC/error-codes" class=''>Error Codes</a></li>
</nav>
</li>
<li>
<a href="/docs/2.9.1/transactions/mvcc"
class=''
>Multiversion Concurrency Control</a>
</li>
<li>
<a href="/docs/2.9.1/SQL/sql-statistics"
class=''
>SQL Statistics</a>
</li>
</nav>
</li>
<li>
<button type='button' class='group-toggle collapsed '>SQL Reference<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class='nav-group collapsed'>
<li>
<a href="/docs/2.9.1/sql-reference/sql-conformance"
class=''
>SQL Conformance</a>
</li>
<li>
<a href="/docs/2.9.1/sql-reference/ddl"
class=''
>Data Definition Language (DDL)</a>
</li>
<li>
<a href="/docs/2.9.1/sql-reference/dml"
class=''
>Data Manipulation Language (DML)</a>
</li>
<li>
<a href="/docs/2.9.1/sql-reference/transactions"
class=''
>Transactions</a>
</li>
<li>
<a href="/docs/2.9.1/sql-reference/operational-commands"
class=''
>Operational Commands</a>
</li>
<li>
<a href="/docs/2.9.1/sql-reference/aggregate-functions"
class=''
>Aggregate functions</a>
</li>
<li>
<a href="/docs/2.9.1/sql-reference/numeric-functions"
class=''
>Numeric Functions</a>
</li>
<li>
<a href="/docs/2.9.1/sql-reference/string-functions"
class=''
>String Functions</a>
</li>
<li>
<a href="/docs/2.9.1/sql-reference/date-time-functions"
class=''
>Data and Time Functions</a>
</li>
<li>
<a href="/docs/2.9.1/sql-reference/system-functions"
class=''
>System Functions</a>
</li>
<li>
<a href="/docs/2.9.1/sql-reference/data-types"
class=''
>Data Types</a>
</li>
</nav>
</li>
<li>
<button type='button' class='group-toggle collapsed '>Distributed Computing<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class='nav-group collapsed'>
<li>
<a href="/docs/2.9.1/distributed-computing/distributed-computing"
class=''
>Distributed Computing API</a>
</li>
<li>
<a href="/docs/2.9.1/distributed-computing/cluster-groups"
class=''
>Cluster Groups</a>
</li>
<li>
<a href="/docs/2.9.1/distributed-computing/executor-service"
class=''
>Executor Service</a>
</li>
<li>
<a href="/docs/2.9.1/distributed-computing/map-reduce"
class=''
>MapReduce API</a>
</li>
<li>
<a href="/docs/2.9.1/distributed-computing/load-balancing"
class=''
>Load Balancing</a>
</li>
<li>
<a href="/docs/2.9.1/distributed-computing/fault-tolerance"
class=''
>Fault Tolerance</a>
</li>
<li>
<a href="/docs/2.9.1/distributed-computing/job-scheduling"
class=''
>Job Scheduling</a>
</li>
<li>
<a href="/docs/2.9.1/distributed-computing/collocated-computations"
class=''
>Colocating Computations with Data</a>
</li>
</nav>
</li>
<li>
<button type='button' class='group-toggle collapsed '>Code Deployment<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class='nav-group collapsed'>
<li>
<a href="/docs/2.9.1/code-deployment/deploying-user-code"
class=''
>Deploying User Code</a>
</li>
<li>
<a href="/docs/2.9.1/code-deployment/peer-class-loading"
class=''
>Peer Class Loading</a>
</li>
</nav>
</li>
<li>
<button type='button' class='group-toggle collapsed '>Machine Learning<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class='nav-group collapsed'>
<li>
<a href="/docs/2.9.1/machine-learning/machine-learning"
class=''
>Machine Learning</a>
</li>
<li>
<a href="/docs/2.9.1/machine-learning/partition-based-dataset"
class=''
>Partition Based Dataset</a>
</li>
<li>
<a href="/docs/2.9.1/machine-learning/updating-trained-models"
class=''
>Updating Trained Models</a>
</li>
<li>
<button
type='button'
class='collapsed '>Binary Classification<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class="sub_pages collapsed">
<li><a href="/docs/2.9.1/machine-learning/binary-classification/introduction" class=''>Introduction</a></li>
<li><a href="/docs/2.9.1/machine-learning/binary-classification/linear-svm" class=''>Linear SVM (Support Vector Machine)</a></li>
<li><a href="/docs/2.9.1/machine-learning/binary-classification/decision-trees" class=''>Decision Trees</a></li>
<li><a href="/docs/2.9.1/machine-learning/binary-classification/multilayer-perceptron" class=''>Multilayer Perceptron</a></li>
<li><a href="/docs/2.9.1/machine-learning/binary-classification/logistic-regression" class=''>Logistic Regression</a></li>
<li><a href="/docs/2.9.1/machine-learning/binary-classification/knn-classification" class=''>k-NN Classification</a></li>
<li><a href="/docs/2.9.1/machine-learning/binary-classification/ann" class=''>ANN (Approximate Nearest Neighbor)</a></li>
<li><a href="/docs/2.9.1/machine-learning/binary-classification/naive-bayes" class=''>Naive Bayes</a></li>
</nav>
</li>
<li>
<button
type='button'
class='collapsed '>Regression<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class="sub_pages collapsed">
<li><a href="/docs/2.9.1/machine-learning/regression/introduction" class=''>Introduction</a></li>
<li><a href="/docs/2.9.1/machine-learning/regression/linear-regression" class=''>Linear Regression</a></li>
<li><a href="/docs/2.9.1/machine-learning/regression/decision-trees-regression" class=''>Decision Trees Regression</a></li>
<li><a href="/docs/2.9.1/machine-learning/regression/knn-regression" class=''>k-NN Regression</a></li>
</nav>
</li>
<li>
<button
type='button'
class='collapsed '>Clustering<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class="sub_pages collapsed">
<li><a href="/docs/2.9.1/machine-learning/clustering/introduction" class=''>Introduction</a></li>
<li><a href="/docs/2.9.1/machine-learning/clustering/k-means-clustering" class=''>K-Means Clustering</a></li>
<li><a href="/docs/2.9.1/machine-learning/clustering/gaussian-mixture" class=''>Gaussian mixture (GMM)</a></li>
</nav>
</li>
<li>
<a href="/docs/2.9.1/machine-learning/preprocessing"
class=''
>Preprocessing</a>
</li>
<li>
<button
type='button'
class='collapsed '>Model Selection<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class="sub_pages collapsed">
<li><a href="/docs/2.9.1/machine-learning/model-selection/introduction" class=''>Introduction</a></li>
<li><a href="/docs/2.9.1/machine-learning/model-selection/evaluator" class=''>Evaluator</a></li>
<li><a href="/docs/2.9.1/machine-learning/model-selection/split-the-dataset-on-test-and-train-datasets" class=''>Split the dataset on test and train datasets</a></li>
<li><a href="/docs/2.9.1/machine-learning/model-selection/hyper-parameter-tuning" class=''>Hyper-parameter tuning</a></li>
<li><a href="/docs/2.9.1/machine-learning/model-selection/pipeline-api" class=''>Pipeline API</a></li>
</nav>
</li>
<li>
<a href="/docs/2.9.1/machine-learning/multiclass-classification"
class=''
>Multiclass Classification</a>
</li>
<li>
<button
type='button'
class='collapsed '>Ensemble Methods<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class="sub_pages collapsed">
<li><a href="/docs/2.9.1/machine-learning/ensemble-methods/introduction" class=''></a></li>
<li><a href="/docs/2.9.1/machine-learning/ensemble-methods/stacking" class=''>Stacking</a></li>
<li><a href="/docs/2.9.1/machine-learning/ensemble-methods/baggin" class=''>Bagging</a></li>
<li><a href="/docs/2.9.1/machine-learning/ensemble-methods/random-forest" class=''>Random Forest</a></li>
<li><a href="/docs/2.9.1/machine-learning/ensemble-methods/gradient-boosting" class=''>Gradient Boosting</a></li>
</nav>
</li>
<li>
<a href="/docs/2.9.1/machine-learning/recommendation-systems"
class=''
>Recommendation Systems</a>
</li>
<li>
<button
type='button'
class='collapsed '>Importing Model<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class="sub_pages collapsed">
<li><a href="/docs/2.9.1/machine-learning/importing-model/introduction" class=''>Introduction</a></li>
<li><a href="/docs/2.9.1/machine-learning/importing-model/model-import-from-gxboost" class=''>Import Model from XGBoost</a></li>
<li><a href="/docs/2.9.1/machine-learning/importing-model/model-import-from-apache-spark" class=''>Import Model from Apache Spark</a></li>
</nav>
</li>
</nav>
</li>
<li>
<a href="/docs/2.9.1/key-value-api/continuous-queries" class='' >Using Continuous Queries</a>
</li>
<li>
<a href="/docs/2.9.1/services/services" class='' >Using Ignite Services</a>
</li>
<li>
<a href="/docs/2.9.1/messaging" class='' >Using Ignite Messaging</a>
</li>
<li>
<button type='button' class='group-toggle collapsed '>Distributed Data Structures<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class='nav-group collapsed'>
<li>
<a href="/docs/2.9.1/data-structures/queue-and-set"
class=''
>Queue and Set</a>
</li>
<li>
<a href="/docs/2.9.1/data-structures/atomic-types"
class=''
>Atomic Types</a>
</li>
<li>
<a href="/docs/2.9.1/data-structures/countdownlatch"
class=''
>CountDownLatch</a>
</li>
<li>
<a href="/docs/2.9.1/data-structures/atomic-sequence"
class=''
>Atomic Sequence</a>
</li>
<li>
<a href="/docs/2.9.1/data-structures/semaphore"
class=''
>Semaphore</a>
</li>
<li>
<a href="/docs/2.9.1/data-structures/id-generator"
class=''
>ID Generator</a>
</li>
</nav>
</li>
<li>
<a href="/docs/2.9.1/distributed-locks" class='' >Distributed Locks</a>
</li>
<li>
<a href="/docs/2.9.1/restapi" class='' >REST API</a>
</li>
<li>
<button type='button' class='group-toggle collapsed '>.NET Specific<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class='nav-group collapsed'>
<li>
<a href="/docs/2.9.1/net-specific/net-configuration-options"
class=''
>Configuration Options</a>
</li>
<li>
<a href="/docs/2.9.1/net-specific/net-deployment-options"
class=''
>Deployment Options</a>
</li>
<li>
<a href="/docs/2.9.1/net-specific/net-standalone-nodes"
class=''
>Standalone Nodes</a>
</li>
<li>
<a href="/docs/2.9.1/net-specific/net-async"
class=''
>Asynchronous APIs</a>
</li>
<li>
<a href="/docs/2.9.1/net-specific/net-logging"
class=''
>Logging</a>
</li>
<li>
<a href="/docs/2.9.1/net-specific/net-linq"
class=''
>LINQ</a>
</li>
<li>
<a href="/docs/2.9.1/net-specific/net-java-services-execution"
class=''
>Java Services Execution</a>
</li>
<li>
<a href="/docs/2.9.1/net-specific/net-platform-cache"
class=''
>.NET Platform Cache</a>
</li>
<li>
<a href="/docs/2.9.1/net-specific/net-plugins"
class=''
>Plugins</a>
</li>
<li>
<a href="/docs/2.9.1/net-specific/net-serialization"
class=''
>Serialization</a>
</li>
<li>
<a href="/docs/2.9.1/net-specific/net-cross-platform-support"
class=''
>Cross-Platform Support</a>
</li>
<li>
<a href="/docs/2.9.1/net-specific/net-platform-interoperability"
class=''
>Platform Interoperability</a>
</li>
<li>
<a href="/docs/2.9.1/net-specific/net-remote-assembly-loading"
class=''
>Remote Assembly Loading</a>
</li>
<li>
<a href="/docs/2.9.1/net-specific/net-troubleshooting"
class=''
>Troubleshooting</a>
</li>
<li>
<button
type='button'
class='collapsed '>Integrations<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class="sub_pages collapsed">
<li><a href="/docs/2.9.1/net-specific/asp-net-output-caching" class=''>ASP.NET Output Caching</a></li>
<li><a href="/docs/2.9.1/net-specific/asp-net-session-state-caching" class=''>ASP.NET Session State Caching</a></li>
<li><a href="/docs/2.9.1/net-specific/net-entity-framework-cache" class=''>Entity Framework 2nd Level Cache</a></li>
</nav>
</li>
</nav>
</li>
<li>
<button type='button' class='group-toggle collapsed '>C++ Specific<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class='nav-group collapsed'>
<li>
<a href="/docs/2.9.1/cpp-specific/cpp-serialization"
class=''
>Serialization</a>
</li>
<li>
<a href="/docs/2.9.1/cpp-specific/cpp-platform-interoperability"
class=''
>Platform Interoperability</a>
</li>
<li>
<a href="/docs/2.9.1/cpp-specific/cpp-objects-lifetime"
class=''
>Objects Lifetime</a>
</li>
</nav>
</li>
<li>
<button type='button' class='group-toggle collapsed '>Monitoring<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class='nav-group collapsed'>
<li>
<a href="/docs/2.9.1/monitoring-metrics/intro"
class=''
>Introduction</a>
</li>
<li>
<a href="/docs/2.9.1/monitoring-metrics/cluster-id"
class=''
>Cluster ID and Tag</a>
</li>
<li>
<a href="/docs/2.9.1/monitoring-metrics/cluster-states"
class=''
>Cluster States</a>
</li>
<li>
<button
type='button'
class='collapsed '>Metrics<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class="sub_pages collapsed">
<li><a href="/docs/2.9.1/monitoring-metrics/configuring-metrics" class=''>Configuring Metrics</a></li>
<li><a href="/docs/2.9.1/monitoring-metrics/metrics" class=''>JMX Metrics</a></li>
</nav>
</li>
<li>
<button
type='button'
class='collapsed '>New Metrics System<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class="sub_pages collapsed">
<li><a href="/docs/2.9.1/monitoring-metrics/new-metrics-system" class=''>Introduction</a></li>
<li><a href="/docs/2.9.1/monitoring-metrics/new-metrics" class=''>Metrics</a></li>
</nav>
</li>
<li>
<a href="/docs/2.9.1/monitoring-metrics/system-views"
class=''
>System Views</a>
</li>
<li>
<a href="/docs/2.9.1/monitoring-metrics/performance-statistics"
class=''
>Performance Statistics</a>
</li>
<li>
<a href="/docs/2.9.1/monitoring-metrics/tracing"
class=''
>Tracing</a>
</li>
</nav>
</li>
<li>
<button type='button' class='group-toggle collapsed '>Working with Events<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class='nav-group collapsed'>
<li>
<a href="/docs/2.9.1/events/listening-to-events"
class=''
>Enabling and Listenting to Events</a>
</li>
<li>
<a href="/docs/2.9.1/events/events"
class=''
>Events</a>
</li>
</nav>
</li>
<li>
<button type='button' class='group-toggle collapsed '>Tools<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class='nav-group collapsed'>
<li>
<a href="/docs/2.9.1/tools/control-script"
class=''
>Control Script</a>
</li>
<li>
<a href="/docs/2.9.1/tools/visor-cmd"
class=''
>Visor CMD</a>
</li>
<li>
<a href="/docs/2.9.1/tools/gg-control-center"
class=''
>GridGain Control Center</a>
</li>
<li>
<a href="/docs/2.9.1/tools/sqlline"
class=''
>SQLLine</a>
</li>
<li>
<a href="/docs/2.9.1/tools/tableau"
class=''
>Tableau</a>
</li>
<li>
<a href="/docs/2.9.1/tools/informatica"
class=''
>Informatica</a>
</li>
<li>
<a href="/docs/2.9.1/tools/pentaho"
class=''
>Pentaho</a>
</li>
</nav>
</li>
<li>
<button type='button' class='group-toggle collapsed '>Security<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class='nav-group collapsed'>
<li>
<a href="/docs/2.9.1/security/authentication"
class=''
>Authentication</a>
</li>
<li>
<a href="/docs/2.9.1/security/ssl-tls"
class=''
>SSL/TLS</a>
</li>
<li>
<button
type='button'
class='collapsed '>Transparent Data Encryption<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class="sub_pages collapsed">
<li><a href="/docs/2.9.1/security/tde" class=''>Introduction</a></li>
<li><a href="/docs/2.9.1/security/master-key-rotation" class=''>Master key rotation</a></li>
<li><a href="/docs/2.9.1/security/cache-encryption-key-rotation" class=''>Cache encryption key rotation</a></li>
</nav>
</li>
<li>
<a href="/docs/2.9.1/security/sandbox"
class=''
>Sandbox</a>
</li>
</nav>
</li>
<li>
<button type='button' class='group-toggle collapsed '>Extensions and Integrations<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class='nav-group collapsed'>
<li>
<button
type='button'
class='collapsed '>Spring<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class="sub_pages collapsed">
<li><a href="/docs/2.9.1/extensions-and-integrations/spring/spring-boot" class=''>Spring Boot</a></li>
<li><a href="/docs/2.9.1/extensions-and-integrations/spring/spring-data" class=''>Spring Data</a></li>
<li><a href="/docs/2.9.1/extensions-and-integrations/spring/spring-caching" class=''>Spring Caching</a></li>
<li><a href="/docs/2.9.1/extensions-and-integrations/spring/spring-tx" class=''>Spring Transactions</a></li>
</nav>
</li>
<li>
<button
type='button'
class='collapsed '>Ignite for Spark<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class="sub_pages collapsed">
<li><a href="/docs/2.9.1/extensions-and-integrations/ignite-for-spark/overview" class=''>Overview</a></li>
<li><a href="/docs/2.9.1/extensions-and-integrations/ignite-for-spark/ignitecontext-and-rdd" class=''>IgniteContext and IgniteRDD</a></li>
<li><a href="/docs/2.9.1/extensions-and-integrations/ignite-for-spark/ignite-dataframe" class=''>Ignite DataFrame</a></li>
<li><a href="/docs/2.9.1/extensions-and-integrations/ignite-for-spark/installation" class=''>Installation</a></li>
<li><a href="/docs/2.9.1/extensions-and-integrations/ignite-for-spark/spark-shell" class=''>Test Ignite with Spark-shell</a></li>
<li><a href="/docs/2.9.1/extensions-and-integrations/ignite-for-spark/troubleshooting" class=''>Troubleshooting</a></li>
</nav>
</li>
<li>
<a href="/docs/2.9.1/extensions-and-integrations/hibernate-l2-cache"
class=''
>Hibernate L2 Cache</a>
</li>
<li>
<a href="/docs/2.9.1/extensions-and-integrations/mybatis-l2-cache"
class=''
>MyBatis L2 Cache</a>
</li>
<li>
<button
type='button'
class='collapsed '>Streaming<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class="sub_pages collapsed">
<li><a href="/docs/2.9.1/extensions-and-integrations/streaming/kafka-streamer" class=''>Kafka Streamer</a></li>
<li><a href="/docs/2.9.1/extensions-and-integrations/streaming/camel-streamer" class=''>Camel Streamer</a></li>
<li><a href="/docs/2.9.1/extensions-and-integrations/streaming/flink-streamer" class=''>Flink Streamer</a></li>
<li><a href="/docs/2.9.1/extensions-and-integrations/streaming/flume-sink" class=''>Flume Sink</a></li>
<li><a href="/docs/2.9.1/extensions-and-integrations/streaming/jms-streamer" class=''>JMS Streamer</a></li>
<li><a href="/docs/2.9.1/extensions-and-integrations/streaming/mqtt-streamer" class=''>MQTT Streamer</a></li>
<li><a href="/docs/2.9.1/extensions-and-integrations/streaming/rocketmq-streamer" class=''>RocketMQ Streamer</a></li>
<li><a href="/docs/2.9.1/extensions-and-integrations/streaming/storm-streamer" class=''>Storm Streamer</a></li>
<li><a href="/docs/2.9.1/extensions-and-integrations/streaming/zeromq-streamer" class=''>ZeroMQ Streamer</a></li>
<li><a href="/docs/2.9.1/extensions-and-integrations/streaming/twitter-streamer" class=''>Twitter Streamer</a></li>
</nav>
</li>
<li>
<button
type='button'
class='collapsed '>Cassandra Integration<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class="sub_pages collapsed">
<li><a href="/docs/2.9.1/extensions-and-integrations/cassandra/overview" class=''>Overview</a></li>
<li><a href="/docs/2.9.1/extensions-and-integrations/cassandra/configuration" class=''>Configuration</a></li>
<li><a href="/docs/2.9.1/extensions-and-integrations/cassandra/usage-examples" class=''>Usage Examples</a></li>
<li><a href="/docs/2.9.1/extensions-and-integrations/cassandra/ddl-generator" class=''>DDL Generator</a></li>
</nav>
</li>
<li>
<a href="/docs/2.9.1/extensions-and-integrations/php-pdo"
class=''
>PHP PDO</a>
</li>
<li>
<a href="/docs/2.9.1/extensions-and-integrations/performance-statistics"
class=''
>Performance Statistics</a>
</li>
</nav>
</li>
<li>
<a href="/docs/2.9.1/plugins" class='' >Plugins</a>
</li>
<li>
<button type='button' class='group-toggle expanded '>Performance and Troubleshooting<img class="state-indicator" src="/assets/images/left-nav-arrow.svg" width="6" height="10"></button>
<nav class='nav-group expanded'>
<li>
<a href="/docs/2.9.1/perf-and-troubleshooting/general-perf-tips"
class=''
>General Performance Tips</a>
</li>
<li>
<a href="/docs/2.9.1/perf-and-troubleshooting/memory-tuning"
class=''
>Memory and JVM Tuning</a>
</li>
<li>
<a href="/docs/2.9.1/perf-and-troubleshooting/persistence-tuning"
class=''
>Persistence Tuning</a>
</li>
<li>
<a href="/docs/2.9.1/perf-and-troubleshooting/sql-tuning"
class='active'
>SQL Tuning</a>
</li>
<li>
<a href="/docs/2.9.1/perf-and-troubleshooting/thread-pools-tuning"
class=''
>Thread Pools Tuning</a>
</li>
<li>
<a href="/docs/2.9.1/perf-and-troubleshooting/troubleshooting"
class=''
>Troubleshooting and Debugging</a>
</li>
<li>
<a href="/docs/2.9.1/perf-and-troubleshooting/handling-exceptions"
class=''
>Handling Exceptions</a>
</li>
<li>
<a href="/docs/2.9.1/perf-and-troubleshooting/yardstick-benchmarking"
class=''
>Benchmarking With Yardstick</a>
</li>
</nav>
</li>
</nav>
<div class="left-nav__overlay"></div>
<article data-swiftype-index='true'>
<a class='edit-link' href="https://github.com/apache/ignite/tree/IGNITE-7595/docs/_docs/perf-and-troubleshooting/sql-tuning.adoc" target="_blank">Edit</a>
<h1>SQL Performance Tuning</h1>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>This article outlines basic and advanced optimization techniques for Ignite SQL queries. Some of the sections are also useful for debugging and troubleshooting.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="basic-considerations-ignite-vs-rdbms">Basic Considerations: Ignite vs RDBMS</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Ignite is frequently compared to relational databases for their SQL capabilities with an expectation that existing SQL
queries, created for an RDBMS, will work out of the box and perform faster in Ignite without any
changes. Usually, such an assumption is based on the fact that Ignite stores and processes data in-memory.
However, it&#8217;s not enough just to put data in RAM and expect an order of magnitude increase in performance. Generally,
extra tuning is required. Below you can see a standard checklist of
best practices to consider before you benchmark Ignite against an RDBMS or do any performance testing:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Ignite is optimized for <em>multi-nodes</em> deployments with RAM as a primary storage. Don&#8217;t
try to compare a single-node Ignite cluster to a relational database. You should deploy a multi-node Ignite cluster with the whole copy of data in RAM.</p>
</li>
<li>
<p>Be ready to adjust your data model and existing SQL queries.
Use the <a href="/docs/2.9.1/data-modeling/affinity-collocation">affinity colocation</a> concept during the data
modelling phase for proper data distribution. Remember, it&#8217;s not enough just to put data in RAM. If your data is properly colocated, you can run SQL queries with JOINs at massive scale and expect significant performance benefits.</p>
</li>
<li>
<p>Define secondary indexes and use other standard, and Ignite-specific, tuning techniques described below.</p>
</li>
<li>
<p>Keep in mind that relational databases leverage local caching techniques and, depending on the total data size, an
RDBMS can complete <em>some queries</em> even faster than Ignite even in a multi-node configuration.
If your data set is around 10-100GB and an RDBMS has enough RAM for caching data locally than it, for instance, can
outperform a multi-node Ignite cluster because the latter will be utilizing the network. Store much more data in Ignite to see the difference.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="using-the-explain-statement">Using the EXPLAIN Statement</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Ignite supports the <code>EXPLAIN</code> statement which could be used to read the execution plan of a query.
Use this command to analyse your queries for possible optimization. Note that the plan will contain multiple rows: the
last one will contain a query for the reducing side (usually your application), others are for map nodes (usually server nodes).
Read the <a href="/docs/2.9.1/SQL/sql-introduction#distributed-queries">Distributed Queries</a> section to learn how queries are executed in Ignite.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sql"><span class="k">EXPLAIN</span> <span class="k">SELECT</span> <span class="n">name</span> <span class="k">FROM</span> <span class="n">Person</span> <span class="k">WHERE</span> <span class="n">age</span> <span class="o">=</span> <span class="mi">26</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>The execution plan is generated by H2 as described <a href="http://www.h2database.com/html/performance.html#explain_plan" target="_blank" rel="noopener">here</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="or-operator-and-selectivity">OR Operator and Selectivity</h2>
<div class="sectionbody">
<div class="paragraph">
<p>If a query contains an <code>OR</code> operator, then indexes may not be used as expected depending on the complexity of the query.
For example, for the query <code>select name from Person where gender='M' and (age = 20 or age = 30)</code>, an index on the <code>gender</code>
field will be used instead of an index on the <code>age</code> field, although the latter is a more selective index.
As a workaround for this issue, you can rewrite the query with <code>UNION ALL</code> (notice that <code>UNION</code> without <code>ALL</code> will return
<code>DISTINCT</code> rows, which will change the query semantics and will further penalize your query performance):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sql"><span class="k">SELECT</span> <span class="n">name</span> <span class="k">FROM</span> <span class="n">Person</span> <span class="k">WHERE</span> <span class="n">gender</span><span class="o">=</span><span class="s1">'M'</span> <span class="k">and</span> <span class="n">age</span> <span class="o">=</span> <span class="mi">20</span>
<span class="k">UNION</span> <span class="k">ALL</span>
<span class="k">SELECT</span> <span class="n">name</span> <span class="k">FROM</span> <span class="n">Person</span> <span class="k">WHERE</span> <span class="n">gender</span><span class="o">=</span><span class="s1">'M'</span> <span class="k">and</span> <span class="n">age</span> <span class="o">=</span> <span class="mi">30</span></code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="avoid-having-too-many-columns">Avoid Having Too Many Columns</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Avoid having too many columns in the result set of a <code>SELECT</code> query. Due to limitations of the H2 query parser, queries
with 100+ columns may perform worse than expected.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="lazy-loading">Lazy Loading</h2>
<div class="sectionbody">
<div class="paragraph">
<p>By default, Ignite attempts to load the whole result set to memory and send it back to the query initiator (which is
usually your application). This approach provides optimal performance for queries of small or medium result sets.
However, if the result set is too big to fit in the available memory, it can lead to prolonged GC pauses and even <code>OutOfMemoryError</code> exceptions.</p>
</div>
<div class="paragraph">
<p>To minimize memory consumption, at the cost of a moderate performance hit, you can load and process the result sets
lazily by passing the <code>lazy</code> parameter to the JDBC and ODBC connection strings or use a similar method available for Java, .NET, and C++ APIs:</p>
</div>
<code-tabs><code-tab data-tab='Java'><div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="java"><span class="nc">SqlFieldsQuery</span> <span class="n">query</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">SqlFieldsQuery</span><span class="o">(</span><span class="s">"SELECT * FROM Person WHERE id &gt; 10"</span><span class="o">);</span>
<span class="c1">// Result set will be loaded lazily.</span>
<span class="n">query</span><span class="o">.</span><span class="na">setLazy</span><span class="o">(</span><span class="kc">true</span><span class="o">);</span></code></pre>
</div>
</div></code-tab><code-tab data-tab='JDBC'><div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sql"><span class="n">jdbc</span><span class="p">:</span><span class="n">ignite</span><span class="p">:</span><span class="n">thin</span><span class="p">:</span><span class="o">//</span><span class="mi">192</span><span class="p">.</span><span class="mi">168</span><span class="p">.</span><span class="mi">0</span><span class="p">.</span><span class="mi">15</span><span class="o">?</span><span class="n">lazy</span><span class="o">=</span><span class="k">true</span></code></pre>
</div>
</div></code-tab><code-tab data-tab='C#/.NET'><div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="csharp"><span class="kt">var</span> <span class="n">query</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">SqlFieldsQuery</span><span class="p">(</span><span class="s">"SELECT * FROM Person WHERE id &gt; 10"</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">// Result set will be loaded lazily.</span>
<span class="n">Lazy</span> <span class="p">=</span> <span class="k">true</span>
<span class="p">};</span></code></pre>
</div>
</div></code-tab><code-tab data-tab='C++'></code-tab></code-tabs>
</div>
</div>
<div class="sect1">
<h2 id="querying-colocated-data">Querying Colocated Data</h2>
<div class="sectionbody">
<div class="paragraph">
<p>When Ignite executes a distributed query, it sends sub-queries to individual cluster nodes to fetch the data and groups
the results on the reducer node (usually your application).
If you know in advance that the data you are querying is <a href="/docs/2.9.1/data-modeling/affinity-collocation">colocated</a>
by the <code>GROUP BY</code> condition, you can use <code>SqlFieldsQuery.collocated = true</code> to tell the SQL engine to do the grouping on the remote nodes.
This will reduce network traffic between the nodes and query execution time.
When this flag is set to <code>true</code>, the query is executed on individual nodes first and the results are sent to the reducer node for final calculation.</p>
</div>
<div class="paragraph">
<p>Consider the following example, in which we assume that the data is colocated by <code>department_id</code> (in other words, the
<code>department_id</code> field is configured as the affinity key).</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sql"><span class="k">SELECT</span> <span class="k">SUM</span><span class="p">(</span><span class="n">salary</span><span class="p">)</span> <span class="k">FROM</span> <span class="n">Employee</span> <span class="k">GROUP</span> <span class="k">BY</span> <span class="n">department_id</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Because of the nature of the SUM operation, Ignite will sum the salaries across the elements stored on individual nodes,
and then send these sums to the reducer node where the final result will be calculated.
This operation is already distributed, and enabling the <code>collocated</code> flag will only slightly improve performance.</p>
</div>
<div class="paragraph">
<p>Let&#8217;s take a slightly different example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sql"><span class="k">SELECT</span> <span class="k">AVG</span><span class="p">(</span><span class="n">salary</span><span class="p">)</span> <span class="k">FROM</span> <span class="n">Employee</span> <span class="k">GROUP</span> <span class="k">BY</span> <span class="n">department_id</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>In this example, Ignite has to fetch all (<code>salary</code>, <code>department_id</code>) pairs to the reducer node and calculate the results there.
However, if employees are colocated by the <code>department_id</code> field, i.e. employee data for the same department
is stored on the same node, setting <code>SqlFieldsQuery.collocated = true</code> will reduce query execution time because Ignite
will calculate the averages for each department on the individual nodes and send the results to the reducer node for final calculation.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="enforcing-join-order">Enforcing Join Order</h2>
<div class="sectionbody">
<div class="paragraph">
<p>When this flag is set, the query optimizer will not reorder tables in joins.
In other words, the order in which joins are applied during query execution will be the same as specified in the query.
Without this flag, the query optimizer can reorder joins to improve performance.
However, sometimes it might make an incorrect decision.
This flag helps to control and explicitly specify the order of joins instead of relying on the optimizer.</p>
</div>
<div class="paragraph">
<p>Consider the following example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sql"><span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">Person</span> <span class="n">p</span>
<span class="k">JOIN</span> <span class="n">Company</span> <span class="k">c</span> <span class="k">ON</span> <span class="n">p</span><span class="p">.</span><span class="n">company</span> <span class="o">=</span> <span class="k">c</span><span class="p">.</span><span class="n">name</span> <span class="k">where</span> <span class="n">p</span><span class="p">.</span><span class="n">name</span> <span class="o">=</span> <span class="s1">'John Doe'</span>
<span class="k">AND</span> <span class="n">p</span><span class="p">.</span><span class="n">age</span> <span class="o">&gt;</span> <span class="mi">20</span>
<span class="k">AND</span> <span class="n">p</span><span class="p">.</span><span class="n">id</span> <span class="o">&gt;</span> <span class="mi">5000</span>
<span class="k">AND</span> <span class="n">p</span><span class="p">.</span><span class="n">id</span> <span class="o">&lt;</span> <span class="mi">100000</span>
<span class="k">AND</span> <span class="k">c</span><span class="p">.</span><span class="n">name</span> <span class="k">NOT</span> <span class="k">LIKE</span> <span class="s1">'O%'</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>This query contains a join between two tables: <code>Person</code> and <code>Company</code>.
To get the best performance, we should understand which join will return the smallest result set.
The table with the smaller result set size should be given first in the join pair.
To get the size of each result set, let&#8217;s test each part.</p>
</div>
<div class="listingblock">
<div class="title">Q1:</div>
<div class="content">
<pre class="rouge highlight"><code data-lang="sql"><span class="k">SELECT</span> <span class="k">count</span><span class="p">(</span><span class="o">*</span><span class="p">)</span>
<span class="k">FROM</span> <span class="n">Person</span> <span class="n">p</span>
<span class="k">where</span>
<span class="n">p</span><span class="p">.</span><span class="n">name</span> <span class="o">=</span> <span class="s1">'John Doe'</span>
<span class="k">AND</span> <span class="n">p</span><span class="p">.</span><span class="n">age</span> <span class="o">&gt;</span> <span class="mi">20</span>
<span class="k">AND</span> <span class="n">p</span><span class="p">.</span><span class="n">id</span> <span class="o">&gt;</span> <span class="mi">5000</span>
<span class="k">AND</span> <span class="n">p</span><span class="p">.</span><span class="n">id</span> <span class="o">&lt;</span> <span class="mi">100000</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">Q2:</div>
<div class="content">
<pre class="rouge highlight"><code data-lang="sql"><span class="k">SELECT</span> <span class="k">count</span><span class="p">(</span><span class="o">*</span><span class="p">)</span>
<span class="k">FROM</span> <span class="n">Company</span> <span class="k">c</span>
<span class="k">where</span>
<span class="k">c</span><span class="p">.</span><span class="n">name</span> <span class="k">NOT</span> <span class="k">LIKE</span> <span class="s1">'O%'</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>After running Q1 and Q2, we can get two different outcomes:</p>
</div>
<div class="paragraph">
<p>Case 1:</p>
</div>
<table class="tableblock frame-all grid-all stripes-none fit-content">
<colgroup>
<col>
<col>
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Q1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">30000</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Q2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">100000</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>Q2 returns more entries than Q1.
In this case, we don&#8217;t need to modify the original query, because smaller subset has already been located on the left side of the join.</p>
</div>
<div class="paragraph">
<p>Case 2:</p>
</div>
<table class="tableblock frame-all grid-all stripes-none fit-content">
<colgroup>
<col>
<col>
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Q1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">50000</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Q2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">10000</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>Q1 returns more entries than Q2. So we need to change the initial query as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sql"><span class="k">SELECT</span> <span class="o">*</span>
<span class="k">FROM</span> <span class="n">Company</span> <span class="k">c</span>
<span class="k">JOIN</span> <span class="n">Person</span> <span class="n">p</span>
<span class="k">ON</span> <span class="n">p</span><span class="p">.</span><span class="n">company</span> <span class="o">=</span> <span class="k">c</span><span class="p">.</span><span class="n">name</span>
<span class="k">where</span>
<span class="n">p</span><span class="p">.</span><span class="n">name</span> <span class="o">=</span> <span class="s1">'John Doe'</span>
<span class="k">AND</span> <span class="n">p</span><span class="p">.</span><span class="n">age</span> <span class="o">&gt;</span> <span class="mi">20</span>
<span class="k">AND</span> <span class="n">p</span><span class="p">.</span><span class="n">id</span> <span class="o">&gt;</span> <span class="mi">5000</span>
<span class="k">AND</span> <span class="n">p</span><span class="p">.</span><span class="n">id</span> <span class="o">&lt;</span> <span class="mi">100000</span>
<span class="k">AND</span> <span class="k">c</span><span class="p">.</span><span class="n">name</span> <span class="k">NOT</span> <span class="k">LIKE</span> <span class="s1">'O%'</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>The force join order hint can be specified as follows:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="/docs/2.9.1/SQL/JDBC/jdbc-driver#parameters">JDBC driver connection parameter</a></p>
</li>
<li>
<p><a href="/docs/2.9.1/SQL/ODBC/connection-string-dsn#supported-arguments">ODBC driver connection attribute</a></p>
</li>
<li>
<p>If you use <a href="/docs/2.9.1/SQL/sql-api">SqlFieldsQuery</a> to execute SQL queries, you can set the enforce join order
hint by calling the <code>SqlFieldsQuery.setEnforceJoinOrder(true)</code> method.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="increasing-index-inline-size">Increasing Index Inline Size</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Every entry in the index has a constant size which is calculated during index creation. This size is called <em>index inline size</em>.
Ideally this size should be enough to store full indexed entry in serialized form.
When values are not fully included in the index, Ignite may need to perform additional data page reads during index lookup,
which can impair performance if persistence is enabled.</p>
</div>
<div class="paragraph">
<p>Here is how values are stored in the index:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="java"><span class="tok-kt">int</span>
0 1 5
| tag | value |
<span class="tok-k">Total: 5 bytes</span>
<span class="tok-kt">long</span>
0 1 9
| tag | value |
<span class="tok-k">Total: 9 bytes</span>
<span class="tok-kt">String</span>
0 1 3 N
| tag | size | UTF-8 value |
<span class="tok-k">Total: 3 + string length</span>
<span class="tok-kt">POJO (BinaryObject)</span>
0 1 5
| tag | BO hash |
<span class="tok-k">Total: 5</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>For primitive data types (bool, byte, short, int, etc.), Ignite automatically calculates the index inline size so that the values are included in full.
For example, for <code>int</code> fields, the inline size is 5 (1 byte for the tag and 4 bytes for the value itself). For <code>long</code> fields, the inline size is 9 (1 byte for the tag + 8 bytes for the value).</p>
</div>
<div class="paragraph">
<p>For binary objects, the index includes the hash of each object, which is enough to avoid collisions. The inline size is 5.</p>
</div>
<div class="paragraph">
<p>For variable length data, indexes include only first several bytes of the value.
Therefore, when indexing fields with variable-length data, we recommend that you estimate the length of your field values and set the inline size to a value that includes most (about 95%) or all values.
For example, if you have a <code>String</code> field with 95% of the values containing 10 characters or fewer, you can set the inline size for the index on that field to 13.</p>
</div>
<div class="paragraph">
<p>The inline sizes explained above apply to single field indexes.
However, when you define an index on a field in the value object or on a non-primary key column, Ignite creates a <em>composite index</em>
by appending the primary key to the indexed value.
Therefore, when calculating the inline size for composite indexes, add up the inline size of the primary key.</p>
</div>
<div class="paragraph">
<p>Below is an example of index inline size calculation for a cache where both key and value are complex objects.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Key</span> <span class="o">{</span>
<span class="nd">@QuerySqlField</span>
<span class="kd">private</span> <span class="kt">long</span> <span class="n">id</span><span class="o">;</span>
<span class="nd">@QuerySqlField</span>
<span class="nd">@AffinityKeyMapped</span>
<span class="kd">private</span> <span class="kt">long</span> <span class="n">affinityKey</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Value</span> <span class="o">{</span>
<span class="nd">@QuerySqlField</span><span class="o">(</span><span class="n">index</span> <span class="o">=</span> <span class="kc">true</span><span class="o">)</span>
<span class="kd">private</span> <span class="kt">long</span> <span class="n">longField</span><span class="o">;</span>
<span class="nd">@QuerySqlField</span><span class="o">(</span><span class="n">index</span> <span class="o">=</span> <span class="kc">true</span><span class="o">)</span>
<span class="kd">private</span> <span class="kt">int</span> <span class="n">intField</span><span class="o">;</span>
<span class="nd">@QuerySqlField</span><span class="o">(</span><span class="n">index</span> <span class="o">=</span> <span class="kc">true</span><span class="o">)</span>
<span class="kd">private</span> <span class="nc">String</span> <span class="n">stringField</span><span class="o">;</span> <span class="c1">// we suppose that 95% of the values are 10 symbols</span>
<span class="o">}</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>The following table summarizes the inline index sizes for the indexes defined in the example above.</p>
</div>
<table class="tableblock frame-all grid-all stripes-even stretch">
<colgroup>
<col style="width: 20%;">
<col style="width: 20%;">
<col style="width: 20%;">
<col style="width: 40%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Index</th>
<th class="tableblock halign-left valign-top">Kind</th>
<th class="tableblock halign-left valign-top">Recommended Inline Size</th>
<th class="tableblock halign-left valign-top">Comment</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">(_key)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Primary key index</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">5</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Inlined hash of a binary object (5)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">(affinityKey, _key)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Affinity key index</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">14</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Inlined long (9) + binary object&#8217;s hash (5)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">(longField, _key)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Secondary index</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">14</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Inlined long (9) + binary object&#8217;s hash (5)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">(intField, _key)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Secondary index</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">10</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Inlined int (5) + binary object up to hash (5)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">(stringField, _key)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Secondary index</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">18</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Inlined string (13) + binary object&#8217;s hash (5) (assuming that the string is ~10 symbols)</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>Note that you will only have to set the inline size for the index on <code>stringField</code>. For other indexes, Ignite will calculate the inline size automatically.</p>
</div>
<div class="paragraph">
<p>Refer to the <a href="/docs/2.9.1/SQL/indexes#configuring-index-inline-size">Configuring Index Inline Size</a> section for the information on how to change the inline size.</p>
</div>
<div class="paragraph">
<p>You can check the inline size of an existing index in the <a href="/docs/2.9.1/monitoring-metrics/system-views#indexes-view">INDEXES</a> system view.</p>
</div>
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<div class="title">Warning</div>
</td>
<td class="content">
<div class="paragraph">
<p>Note that since Ignite encodes strings to <code>UTF-8</code>, some characters use more than 1 byte.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="query-parallelism">Query Parallelism</h2>
<div class="sectionbody">
<div class="paragraph">
<p>By default, a SQL query is executed in a single thread on each participating Ignite node. This approach is optimal for
queries returning small result sets involving index search. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sql"><span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">Person</span> <span class="k">WHERE</span> <span class="n">p</span><span class="p">.</span><span class="n">id</span> <span class="o">=</span> <span class="o">?</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Certain queries might benefit from being executed in multiple threads.
This relates to queries with table scans and aggregations, which is often the case for HTAP and OLAP workloads.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sql"><span class="k">SELECT</span> <span class="k">SUM</span><span class="p">(</span><span class="n">salary</span><span class="p">)</span> <span class="k">FROM</span> <span class="n">Person</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>The number of threads created on a single node for query execution is configured per cache and by default equals 1.
You can change the value by setting the <code>CacheConfiguration.queryParallelism</code> parameter.
If you create SQL tables using the CREATE TABLE command, you can use a <a href="/docs/2.9.1/configuring-caches/configuration-overview#cache-templates">cache template</a> to set this parameter.</p>
</div>
<div class="paragraph">
<p>If a query contains <code>JOINs</code>, then all the participating caches must have the same degree of parallelism.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="index-hints">Index Hints</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Index hints are useful in scenarios when you know that one index is more suitable for certain queries than another.
You can use them to instruct the query optimizer to choose a more efficient execution plan.
To do this, you can use <code>USE INDEX(indexA,&#8230;&#8203;,indexN)</code> statement as shown in the following example.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sql"><span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">Person</span> <span class="n">USE</span> <span class="k">INDEX</span><span class="p">(</span><span class="n">index_age</span><span class="p">)</span>
<span class="k">WHERE</span> <span class="n">salary</span> <span class="o">&gt;</span> <span class="mi">150000</span> <span class="k">AND</span> <span class="n">age</span> <span class="o">&lt;</span> <span class="mi">35</span><span class="p">;</span></code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="partition-pruning">Partition Pruning</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Partition pruning is a technique that optimizes queries that use affinity keys in the <code>WHERE</code> condition. When
executing such a query, Ignite will scan only those partitions where the requested data is stored. This will reduce
query time because the query will be sent only to the nodes that store the requested partitions.</p>
</div>
<div class="paragraph">
<p>In the following example, the employee objects are colocated by the <code>id</code> field (if an affinity key is not set
explicitly then the primary key is used as the affinity key):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sql"><span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">employee</span> <span class="p">(</span><span class="n">id</span> <span class="nb">BIGINT</span> <span class="k">PRIMARY</span> <span class="k">KEY</span><span class="p">,</span> <span class="n">department_id</span> <span class="nb">INT</span><span class="p">,</span> <span class="n">name</span> <span class="nb">VARCHAR</span><span class="p">)</span>
<span class="cm">/* This query is sent to the node where the requested key is stored */</span>
<span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">employee</span> <span class="k">WHERE</span> <span class="n">id</span><span class="o">=</span><span class="mi">10</span><span class="p">;</span>
<span class="cm">/* This query is sent to all nodes */</span>
<span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">employee</span> <span class="k">WHERE</span> <span class="n">department_id</span><span class="o">=</span><span class="mi">10</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>In the next example, the affinity key is set explicitly and, therefore, will be used to colocate data and direct
queries to the nodes that keep primary copies of the data:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sql"><span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">employee</span> <span class="p">(</span><span class="n">id</span> <span class="nb">BIGINT</span> <span class="k">PRIMARY</span> <span class="k">KEY</span><span class="p">,</span> <span class="n">department_id</span> <span class="nb">INT</span><span class="p">,</span> <span class="n">name</span> <span class="nb">VARCHAR</span><span class="p">)</span> <span class="k">WITH</span> <span class="nv">"AFFINITY_KEY=department_id"</span>
<span class="cm">/* This query is sent to all nodes */</span>
<span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">employee</span> <span class="k">WHERE</span> <span class="n">id</span><span class="o">=</span><span class="mi">10</span><span class="p">;</span>
<span class="cm">/* This query is sent to the node where the requested key is stored */</span>
<span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">employee</span> <span class="k">WHERE</span> <span class="n">department_id</span><span class="o">=</span><span class="mi">10</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
<div class="paragraph">
<p>Refer to <a href="/docs/2.9.1/data-modeling/affinity-collocation">affinity colocation</a> page for more details
on how data gets colocated and how it helps boost performance in distributed storages like Ignite.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="skip-reducer-on-update">Skip Reducer on Update</h2>
<div class="sectionbody">
<div class="paragraph">
<p>When Ignite executes a DML operation, it first fetches all the affected intermediate rows for analysis to the reducer
node (usually your application), and only then prepares batches of updated values that will be sent to remote nodes.</p>
</div>
<div class="paragraph">
<p>This approach might affect performance and saturate the network if a DML operation has to move many entries.</p>
</div>
<div class="paragraph">
<p>Use this flag as a hint for the SQL engine to do all intermediate rows analysis and updates “in-place” on the server nodes.
The hint is supported for JDBC and ODBC connections.</p>
</div>
<code-tabs><code-tab data-tab='JDBC Connection String'><div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="text">//jdbc connection string
jdbc:ignite:thin://192.168.0.15/skipReducerOnUpdate=true</code></pre>
</div>
</div></code-tab></code-tabs>
</div>
</div>
<div class="sect1">
<h2 id="sql-on-heap-row-cache">SQL On-heap Row Cache</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Ignite stores data and indexes in its own memory space outside of Java heap. This means that with every data
access, a part of the data will be copied from the off-heap space to Java heap, potentially deserialized, and kept in
the heap as long as your application or server node references it.</p>
</div>
<div class="paragraph">
<p>The SQL on-heap row cache is intended to store hot rows (key-value objects) in Java heap, minimizing resources
spent for data copying and deserialization. Each cached row refers to an entry in the off-heap region and can be
invalidated when one of the following happens:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The master entry stored in the off-heap region is updated or removed.</p>
</li>
<li>
<p>The data page that stores the master entry is evicted from RAM.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The on-heap row cache can be enabled for a specific cache/table (if you use CREATE TABLE to create SQL tables and caches,
then the parameter can be passed via a <a href="/docs/2.9.1/configuring-caches/configuration-overview#cache-templates">cache template</a>):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="xml"><span class="nt">&lt;bean</span> <span class="na">class=</span><span class="s">"org.apache.ignite.configuration.IgniteConfiguration"</span><span class="nt">&gt;</span>
<span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">"cacheConfiguration"</span><span class="nt">&gt;</span>
<span class="nt">&lt;bean</span> <span class="na">class=</span><span class="s">"org.apache.ignite.configuration.CacheConfiguration"</span><span class="nt">&gt;</span>
<span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">"name"</span> <span class="na">value=</span><span class="s">"myCache"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">"sqlOnheapCacheEnabled"</span> <span class="na">value=</span><span class="s">"true"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/bean&gt;</span>
<span class="nt">&lt;/property&gt;</span>
<span class="nt">&lt;/bean&gt;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>If the row cache is enabled, you might be able to trade RAM for performance. You might get up to a 2x performance increase for some SQL queries and use cases by allocating more RAM for rows caching purposes.</p>
</div>
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<div class="title">Warning</div>
</td>
<td class="content">
<h3 id="sql-on-heap-row-cache-size" class="discrete">SQL On-Heap Row Cache Size</h3>
<div class="paragraph">
<p>Presently, the cache is unlimited and can occupy as much RAM as allocated to your memory data regions. Make sure to:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Set the JVM max heap size equal to the total size of all the data regions that store caches for which this on-heap row cache is enabled.</p>
</li>
<li>
<p><a href="/docs/2.9.1/perf-and-troubleshooting/memory-tuning#java-heap-and-gc-tuning">Tune</a> JVM garbage collection accordingly.</p>
</li>
</ul>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="using-timestamp-instead-of-date">Using TIMESTAMP instead of DATE</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Use the <code>TIMESTAMP</code> type instead of <code>DATE</code> whenever possible. Presently, the <code>DATE</code> type is serialized/deserialized very
inefficiently resulting in performance degradation.</p>
</div>
</div>
</div>
<div class="copyright">
© 2021 The Apache Software Foundation.<br/>
Apache, Apache Ignite, the Apache feather and the Apache Ignite logo are either registered trademarks or trademarks of The Apache Software Foundation.
</div>
</article>
<nav class="right-nav" data-swiftype-index='false'>
<div class="toc-wrapper">
<ul class="sectlevel1">
<li><a href="#basic-considerations-ignite-vs-rdbms">Basic Considerations: Ignite vs RDBMS</a></li>
<li><a href="#using-the-explain-statement">Using the EXPLAIN Statement</a></li>
<li><a href="#or-operator-and-selectivity">OR Operator and Selectivity</a></li>
<li><a href="#avoid-having-too-many-columns">Avoid Having Too Many Columns</a></li>
<li><a href="#lazy-loading">Lazy Loading</a></li>
<li><a href="#querying-colocated-data">Querying Colocated Data</a></li>
<li><a href="#enforcing-join-order">Enforcing Join Order</a></li>
<li><a href="#increasing-index-inline-size">Increasing Index Inline Size</a></li>
<li><a href="#query-parallelism">Query Parallelism</a></li>
<li><a href="#index-hints">Index Hints</a></li>
<li><a href="#partition-pruning">Partition Pruning</a></li>
<li><a href="#skip-reducer-on-update">Skip Reducer on Update</a></li>
<li><a href="#sql-on-heap-row-cache">SQL On-heap Row Cache</a></li>
<li><a href="#using-timestamp-instead-of-date">Using TIMESTAMP instead of DATE</a></li>
</ul>
</div>
<nav class="promo-nav">
<!--#include virtual="/includes/docs_rightnav_promotion.html" -->
<a href="#" data-trigger-bugyard-feedback="true" id="doc-feedback-btn">Docs Feedback</a>
</nav>
</nav>
</section>
<script type='module' src='/assets/js/code-copy-to-clipboard.js' async crossorigin></script>
<script>
// inits deep anchors -- needs to be done here because of https://www.bryanbraun.com/anchorjs/#dont-run-it-too-late
anchors.add('.page-docs h1, .page-docs h2, .page-docs h3:not(.discrete), .page-docs h4, .page-docs h5');
anchors.options = {
placement: 'right',
visible: 'always'
};
</script>
<script src="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js"></script>
<script>
docsearch({
// Your apiKey and indexName will be given to you once
// we create your config
apiKey: '3eee686c0ebe39eff3baeb18c56fa5f8',
indexName: 'apache_ignite',
// Replace inputSelector with a CSS selector
// matching your search input
inputSelector: '#search-input',
// algoliaOptions: { 'facetFilters': ["version:$VERSION"] },
// Set debug to true to inspect the dropdown
debug: false,
});
</script>
<script type='module' src='/assets/js/index.js?1639578927' async crossorigin></script>
<script type='module' src='/assets/js/versioning.js?1639578927' async crossorigin></script>
<link rel="stylesheet" href="/assets/css/styles.css?1639578927" media="print" onload="this.media='all'">
<noscript><link media="all" rel="stylesheet" href="/assets/css/styles.css?1639578927"></noscript>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css" media="print" onload="this.media='all'">
<noscript><link media="all" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css"></noscript>
</body>
</html>