企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
<div id="article_content" class="article_content clearfix"> <link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/kdoc_html_views-1a98987dfd.css"> <link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/ck_htmledit_views-25cebea3f9.css"> <div id="content_views" class="htmledit_views"> <h1><a name="t0"></a>1、执行计划调优</h1> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在clickhuse20.6版本之前要查看SQL语句的执行计划需要设置<a href="https://so.csdn.net/so/search?q=%E6%97%A5%E5%BF%97%E7%BA%A7%E5%88%AB&amp;spm=1001.2101.3001.7020" target="_blank" class="hl hl-1" data-report-click="{&quot;spm&quot;:&quot;1001.2101.3001.7020&quot;,&quot;dest&quot;:&quot;https://so.csdn.net/so/search?q=%E6%97%A5%E5%BF%97%E7%BA%A7%E5%88%AB&amp;spm=1001.2101.3001.7020&quot;,&quot;extra&quot;:&quot;{\&quot;searchword\&quot;:\&quot;日志级别\&quot;}&quot;}" data-tit="日志级别" data-pretit="日志级别">日志级别</a>为trace才能可以看到并且只能真正执行sql,在执行日志里面查看。在20.6版本引入了原生的执行计划的语法。在20.6.3版本成为正式版本的功能。</p> <h2><a name="t1"></a>1.1、基本语法</h2> <pre data-index="0"><code class="language-sql hljs"><ol class="hljs-ln" style="width:100%"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">EXPLAIN [AST <span class="hljs-operator">|</span> SYNTAX <span class="hljs-operator">|</span> PLAN <span class="hljs-operator">|</span> PIPELINE] [setting <span class="hljs-operator">=</span> <span class="hljs-keyword">value</span>, ...] </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">select</span> ...[FORMAT ...]</div></div></li></ol></code><div class="hljs-button {2}" data-title="复制" onclick="hljs.copyCode(event)"></div></pre> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PLAN:用于查看执行计划,默认值。</p> <ul><li>header:打印计划中各个步骤的head说明,默认关闭,默认值为 0;</li><li>description:打印计划中各个步骤的描述,默认开启,默认值为1;</li><li>actions:打印计划中各个步骤的详细信息,默认关闭,默认值为0。</li></ul> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="https://so.csdn.net/so/search?q=AST&amp;spm=1001.2101.3001.7020" target="_blank" class="hl hl-1" data-report-click="{&quot;spm&quot;:&quot;1001.2101.3001.7020&quot;,&quot;dest&quot;:&quot;https://so.csdn.net/so/search?q=AST&amp;spm=1001.2101.3001.7020&quot;,&quot;extra&quot;:&quot;{\&quot;searchword\&quot;:\&quot;AST\&quot;}&quot;}" data-tit="AST" data-pretit="ast">AST</a>:用于查看语法树;</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SYNTAX:用于优化语法;</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PIPELINE:用于查看PIPELINE计划。</p> <ul><li>header:打印计划中各个步骤的head说明,默认关闭;</li><li>graph:用DOT图形语言描述管道图,默认关闭,需要查看相关的图形需要配置grapgviz查看;</li><li>actions:如果开启了graph,默认开启。</li></ul> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;注:PLAN和PIPELINE还可以进行额外的显示设置,如上setting。</p> <h2><a name="t2"></a>1.2、案例实操</h2> <h3><a name="t3"></a>1.2.1、新版本使用EXPLAIN</h3> <p>&nbsp; &nbsp; &nbsp; &nbsp; 可以使用20.6以上版本,例如我现使用的为21.7.3.14。或者直接在官网的在线demo,选择高版本进行测试。</p> <p>&nbsp; &nbsp; &nbsp; &nbsp; 官网在线测试链接:<a href="https://play.clickhouse.com/?file=welcome" title="ClickHouse Playground">ClickHouse Playground</a></p> <p>&nbsp; &nbsp; &nbsp; &nbsp; 1、查看PLAN</p> <pre data-index="1"><code class="language-sql hljs"><ol class="hljs-ln" style="width:1355px"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-comment">-- plan 是默认的,可省略</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">explain plan <span class="hljs-keyword">select</span> database,<span class="hljs-keyword">table</span>,<span class="hljs-built_in">count</span>(<span class="hljs-number">1</span>) cnt <span class="hljs-keyword">from</span> system.parts <span class="hljs-keyword">where</span> database <span class="hljs-keyword">in</span> (<span class="hljs-string">'datasets'</span>,<span class="hljs-string">'system'</span>) <span class="hljs-keyword">group</span> <span class="hljs-keyword">by</span> database,</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">table</span> <span class="hljs-keyword">order</span> <span class="hljs-keyword">by</span> database,cnt <span class="hljs-keyword">desc</span> limit <span class="hljs-number">2</span> <span class="hljs-keyword">by</span> database;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">explain header<span class="hljs-operator">=</span><span class="hljs-number">1</span>,actions<span class="hljs-operator">=</span><span class="hljs-number">1</span>,description<span class="hljs-operator">=</span><span class="hljs-number">1</span> <span class="hljs-keyword">select</span> database,<span class="hljs-keyword">table</span>,<span class="hljs-built_in">count</span>(<span class="hljs-number">1</span>) cnt <span class="hljs-keyword">from</span> system.parts <span class="hljs-keyword">where</span> database <span class="hljs-keyword">in</span> (<span class="hljs-string">'datasets'</span>,<span class="hljs-string">'system'</span>) <span class="hljs-keyword">group</span> <span class="hljs-keyword">by</span> database,</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">table</span> <span class="hljs-keyword">order</span> <span class="hljs-keyword">by</span> database,cnt <span class="hljs-keyword">desc</span> limit <span class="hljs-number">2</span> <span class="hljs-keyword">by</span> database;</div></div></li></ol></code><div class="hljs-button {2}" data-title="复制" onclick="hljs.copyCode(event)"></div></pre> <p style="text-align:center;"><img alt="" height="549" src="https://img-blog.csdnimg.cn/f62432c9c61842d0ae53f72738ede70b.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAWXVhbl9DU0RG,size_20,color_FFFFFF,t_70,g_se,x_16" width="941"></p> <p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2、AST<a href="https://so.csdn.net/so/search?q=%E8%AF%AD%E6%B3%95%E6%A0%91&amp;spm=1001.2101.3001.7020" target="_blank" class="hl hl-1" data-report-click="{&quot;spm&quot;:&quot;1001.2101.3001.7020&quot;,&quot;dest&quot;:&quot;https://so.csdn.net/so/search?q=%E8%AF%AD%E6%B3%95%E6%A0%91&amp;spm=1001.2101.3001.7020&quot;,&quot;extra&quot;:&quot;{\&quot;searchword\&quot;:\&quot;语法树\&quot;}&quot;}" data-tit="语法树" data-pretit="语法树">语法树</a>(更深究才会使用到)</p> <pre data-index="2"><code class="language-sql hljs">explain AST <span class="hljs-keyword">SELECT</span> number <span class="hljs-keyword">from</span> system.numbers limit <span class="hljs-number">10</span>;</code><div class="hljs-button {2}" data-title="复制" onclick="hljs.copyCode(event)"></div></pre> <p style="text-align:center;"><img alt="" height="349" src="https://img-blog.csdnimg.cn/1cb6121f2afd4dff88ac31f48de245c7.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAWXVhbl9DU0RG,size_15,color_FFFFFF,t_70,g_se,x_16" width="473"></p> <p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3、SYNTAX语法优化</p> <pre data-index="3"><code class="language-sql hljs"><ol class="hljs-ln" style="width:100%"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-comment">-- 初次查询</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">select</span> number <span class="hljs-operator">=</span><span class="hljs-number">1</span>? <span class="hljs-string">'hello'</span>:(number<span class="hljs-operator">=</span><span class="hljs-number">2</span>?<span class="hljs-string">'world'</span>:<span class="hljs-string">'abcdef'</span>) <span class="hljs-keyword">from</span> numbers(<span class="hljs-number">10</span>);</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-comment">-- 查看语法优化</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">EXPLAIN SYNTAX <span class="hljs-keyword">SELECT</span> number <span class="hljs-operator">=</span><span class="hljs-number">1</span>? <span class="hljs-string">'hello'</span>:(number<span class="hljs-operator">=</span><span class="hljs-number">2</span>?<span class="hljs-string">'world'</span>:<span class="hljs-string">'abcdef'</span>) <span class="hljs-keyword">from</span> numbers(<span class="hljs-number">10</span>);</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="7"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-comment">-- 开启三元运算符优化</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="8"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">set</span> optimize_if_chain_to_multiif <span class="hljs-operator">=</span> <span class="hljs-number">1</span>;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="9"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="10"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-comment">-- 再次查看语法优化</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="11"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">EXPLAIN SYNTAX <span class="hljs-keyword">SELECT</span> number <span class="hljs-operator">=</span><span class="hljs-number">1</span>? <span class="hljs-string">'hello'</span>:(number<span class="hljs-operator">=</span><span class="hljs-number">2</span>?<span class="hljs-string">'world'</span>:<span class="hljs-string">'abcdef'</span>) <span class="hljs-keyword">from</span> numbers(<span class="hljs-number">10</span>);</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="12"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="13"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-comment">-- 返回优化后的语句</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="14"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">SELECT</span> multiIf(number <span class="hljs-operator">=</span> <span class="hljs-number">1</span>, <span class="hljs-string">'hello'</span>, number <span class="hljs-operator">=</span> <span class="hljs-number">2</span>, <span class="hljs-string">'world'</span>, <span class="hljs-string">'abcdef'</span>) <span class="hljs-keyword">FROM</span> numbers(<span class="hljs-number">10</span>)</div></div></li></ol></code><div class="hljs-button {2}" data-title="复制" onclick="hljs.copyCode(event)"></div></pre> <p style="text-align:center;"><img alt="" height="571" src="https://img-blog.csdnimg.cn/7b66e881850d44dc96a1a6b7762a8624.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAWXVhbl9DU0RG,size_20,color_FFFFFF,t_70,g_se,x_16" width="707"></p> <p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4、PIPELINE</p> <p>&nbsp; &nbsp; &nbsp; &nbsp; 可以查看每个步骤使用的并行度:</p> <pre data-index="4"><code class="language-sql hljs"><ol class="hljs-ln" style="width:100%"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">EXPLAIN PIPELINE <span class="hljs-keyword">SELECT</span> <span class="hljs-built_in">sum</span>(number) <span class="hljs-keyword">from</span> numbers_mt(<span class="hljs-number">10000</span>) <span class="hljs-keyword">group</span> <span class="hljs-keyword">by</span> number <span class="hljs-operator">%</span> <span class="hljs-number">20</span>;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">EXPLAIN PIPELINE header<span class="hljs-operator">=</span><span class="hljs-number">1</span>,graph<span class="hljs-operator">=</span><span class="hljs-number">1</span> <span class="hljs-keyword">SELECT</span> <span class="hljs-built_in">sum</span>(number) <span class="hljs-keyword">from</span> numbers_mt(<span class="hljs-number">10000</span>) <span class="hljs-keyword">group</span> <span class="hljs-keyword">by</span> number <span class="hljs-operator">%</span> <span class="hljs-number">20</span>;</div></div></li></ol></code><div class="hljs-button {2}" data-title="复制" onclick="hljs.copyCode(event)"></div></pre> <p style="text-align:center;"><img alt="" height="323" src="https://img-blog.csdnimg.cn/faa0c22cf12c403ea54655a1f370d64b.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAWXVhbl9DU0RG,size_20,color_FFFFFF,t_70,g_se,x_16" width="641"></p> <p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<strong><span style="color:#fe2c24;">在这里最常用的是SYNTAX和PIPELINE,效果显而易见。</span></strong></p> <h3><a name="t4"></a>1.2.2、老版本查看执行计划</h3> <pre data-index="5"><code class="language-bash hljs">clickhouse-client -h 主机名 --send_logs_level=trace &lt;&lt;&lt; <span class="hljs-string">"sql"</span> &gt; /dev/null</code><div class="hljs-button {2}" data-title="复制" onclick="hljs.copyCode(event)"></div></pre> <p>&nbsp; &nbsp; &nbsp; &nbsp; 其中,send_logs_level参数指定日志等级为trace,&lt;&lt;&lt;将SQL语句重定向至clickhouse-client进行查询,&gt;/dev/numm将查询结果重定向到空设备吞掉,以便观察日志。</p> <p>&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#fe2c24;">注意:</span></p> <ol><li><span style="color:#0d0016;">通过将ClickHouse的服务日志,设置到DEBUG或者TRACE级别,才可以变相实现EXPLAIN查询的作用。</span></li><li><span style="color:#0d0016;">需要真正的执行SQL查询,CH才能打印计划日志,所以如果表的数据量很大, 最好借助LIMIT子句,减小查询返回的数据量。</span></li></ol> <h1><a name="t5"></a>2、建表优化</h1> <h2><a name="t6"></a>2.1、数据类型</h2> <h3><a name="t7"></a>2.1.1、时间字段的类型</h3> <p>&nbsp; &nbsp; &nbsp; &nbsp; 建表时能用数值型或日期时间型表示的字段能不用字符串就不要用字符串,全String类型在以Hive为中心的数仓建设中常见,但ClickHouse环境不应受此影响。</p> <p>&nbsp; &nbsp; &nbsp; &nbsp; 虽然ClickHouse底层将DateTime存储为时间戳Long类型,但不建议存储Long类型,因为<span style="color:#fe2c24;">DateTime不需要经过函数转换处理,执行效率高、可读性好</span>。</p> <h3><a name="t8"></a>2.1.2、控制存储类型</h3> <p>&nbsp; &nbsp; &nbsp; &nbsp; 官网已经指出Nullable类型几乎总是会拖累性能,<span style="color:#fe2c24;">因为存储Nullable列时需要创建一个额外的文件来存储NULL的标记,并且Nullable列无法被索引</span>。因为除非极特殊情况,应直接使用字段默认值表示空,或者自行指定一个在业务中无意义的值。</p> <p>&nbsp; &nbsp; &nbsp; &nbsp; 例如:</p> <pre data-index="6"><code class="language-sql hljs"><ol class="hljs-ln" style="width:100%"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> test_null(x Int8,y Nullable(Int8)) ENGINE TinyLog;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">INSERT</span> <span class="hljs-keyword">INTO</span> test_null <span class="hljs-keyword">VALUES</span>(<span class="hljs-number">1</span>,<span class="hljs-keyword">NULL</span>),(<span class="hljs-number">2</span>,<span class="hljs-number">3</span>);</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">SELECT</span> x<span class="hljs-operator">+</span>y <span class="hljs-keyword">FROM</span> test_null;</div></div></li></ol></code><div class="hljs-button {2}" data-title="复制" onclick="hljs.copyCode(event)"></div></pre> <p>&nbsp; &nbsp; &nbsp; &nbsp; 查看存储的文件:</p> <p style="text-align:center;"><img alt="" height="159" src="https://img-blog.csdnimg.cn/5084fa778aaf46ff8d91411b0058158c.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAWXVhbl9DU0RG,size_11,color_FFFFFF,t_70,g_se,x_16" width="360"></p> <h2><a name="t9"></a>2.2、分区和索引</h2> <p>&nbsp; &nbsp; &nbsp; &nbsp; 分区粒度根据业务特点决定,不宜过粗或过细。一般选择按天分区,也可以指定为Tuple(),<strong>以单表一亿数据为例,分区大小控制在10-30个为最佳。</strong></p> <p>&nbsp; &nbsp; &nbsp; &nbsp; 必须指定索引列,ClickHouse中的索引列即排序列,通过order by指定,一般在查询条件中经常被用来充当筛选条件的属性被纳入进来:可以是单一维度,也可以是组合维度的索引;<span style="color:#fe2c24;">通常需要满足高级列在前、查询频率大的在前原则;还有基数特别大的不适合做索引列,如用户表的userid字段;通常筛选后的数据满足在百万以内为最佳。</span></p> <h2><a name="t10"></a><span style="color:#0d0016;">2.3、表参数</span></h2> <p><span style="color:#0d0016;">&nbsp; &nbsp; &nbsp; &nbsp; Index_granularity是用来通知索引粒度的,默认是8192,如非必须不建议调整。</span></p> <p><span style="color:#0d0016;">&nbsp; &nbsp; &nbsp; &nbsp; 如果表中不是必须保留全量历史数据,建议制定TTL(生存时间值)可以免去手动过期历史数据的麻烦,TTL也可以通过alter table语句随时修改。</span></p> <h2><a name="t11"></a><span style="color:#0d0016;">2.4、写入和删除优化</span></h2> <p>&nbsp; &nbsp; &nbsp; &nbsp; 1、尽量不要执行单条或小批量删除和插入操作,这样会产生小分区文件,给后台Merge任务带来巨大压力。</p> <p>&nbsp; &nbsp; &nbsp; &nbsp; 2、不要一次写入太多分区,或数据写入太快,数据写入太快会导致Merge速度跟不上而报错,一般建议每秒钟发起2-3次写入操作(例如flink的并行度),每次操作写入2W~5W条数据(依服务器性能而定)。</p> <h2><a name="t12"></a>2.5、常见配置</h2> <p>&nbsp; &nbsp; &nbsp; &nbsp; 配置项主要在config.xml(对应服务端的配置)或users.xml(用户使用的配置)中,基本上都在users.xml里。目录在/etc/clickhouse-server。</p> <p>&nbsp; &nbsp; &nbsp; &nbsp; 1、config.xml的配置项(<span style="color:#fe2c24;">不能被覆盖,即在客户端设置的参数无法覆盖</span>):</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="https://clickhouse.com/docs/en/operations/server-configuration-parameters/settings/" title="Server Settings | ClickHouse Documentation">Server Settings | ClickHouse Documentation</a></p> <p>&nbsp; &nbsp; &nbsp; &nbsp; 2、users.xml的配置项:</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="https://clickhouse.com/docs/en/operations/settings/" title="Introduction | ClickHouse Documentation">Introduction | ClickHouse Documentation</a></p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p> <p style="text-align:center;"><img alt="" height="842" src="https://img-blog.csdnimg.cn/0a5c2d15ba914a0d833eb7e8570cb119.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAWXVhbl9DU0RG,size_9,color_FFFFFF,t_70,g_se,x_16" width="295"></p> <h3><a name="t13"></a>2.5.1、CPU资源</h3> <div class="table-box"><table align="center" border="1" cellpadding="1" cellspacing="1" style="width:700px;"><thead><tr><th style="text-align:center;">配置</th><th style="text-align:center;">描述</th></tr></thead><tbody><tr><td>background_pool_size</td><td>后台线程池的大小,merge线程就是在该线程池中执行,该线程池不仅仅是给merge线程用的,默认值16,允许的前提下建议改成<span style="color:#fe2c24;">cpu个数的2倍(线程数)</span>。</td></tr><tr><td> <p id="background_schedule_pool_size">background_schedule_pool_size</p> </td><td>执行后台任务(复制表、Kafka流、DNS缓存更新)的线程数。默认128,建议改成<span style="color:#fe2c24;">cpu个数的2倍(线程数)</span>。</td></tr><tr><td>background_distributed_schedule_pool_size</td><td>设置为分布式发送执行后台任务的线程数,默认16,建议改成<span style="color:#fe2c24;">CPU个数的2倍(线程数)</span></td></tr><tr><td>max_concurrent_queries</td><td>最大并发处理的请求数(包含select,insert等),默认值100,推荐<span style="color:#fe2c24;">150(不够再加)~300</span>。</td></tr><tr><td>max_threads</td><td>设置单个查询所能使用的最大cpu个数,默认是cpu核数</td></tr></tbody></table></div> <h3><a name="t14"></a>2.5.2、内存资源</h3> <div class="table-box"><table border="1" cellpadding="1" cellspacing="1" style="width:700px;"><thead><tr><th style="text-align:center;">配置</th><th style="text-align:center;">描述</th></tr></thead><tbody><tr><td>max_memory_usage</td><td>此参数在users.xml中,表示单次Query占用内存最大值,该值可以设置的比较大,这样可以提升集群查询的上限。保留一点给OS,比如<span style="color:#fe2c24;">128G内存的机器,设置为100GB。</span></td></tr><tr><td>max_bytes_before_external_group_by</td><td>一般按照max_memory_usage的一半设置内存,当group使用内存超过阈值后会刷新到磁盘进行。因为clickhouse聚合分两个阶段:查询并及建立中间数据、合并中间数据,<span style="color:#fe2c24;">结合上一项,建议50GB。</span></td></tr><tr><td>max_bytes_before_external_sort</td><td>当order by已使用max_bytes_before_external_sort内存就进行溢写磁盘(基于磁盘排序),如果不设置该值,那么当内存不够时直接抛错,设置了该值order by可以正常完成,但是速度相对存内存来说肯定要慢点(实测慢的非常多,无法接受)。</td></tr><tr><td>max_table_size_to_drop</td><td>此参数在config.xml中,应用于需要删除表或分区的情况,默认是50GB,意思是如果删除50GB以上的分区表会失败。<span style="color:#fe2c24;">建议修改为0</span>,这样不管多大的分区表都可以删除。</td></tr></tbody></table></div> <h3><a name="t15"></a>2.5.3、存储</h3> <p>&nbsp; &nbsp; &nbsp; &nbsp; ClickHouse不支持设置多数据目录,为了提升数据io性能,可以挂载虚拟券组,一个券组绑定多块物理磁盘提升读写性能,多数据查询场景SSD会比普通机械硬盘快2-3倍。</p> <p></p> </div><div data-report-view="{&quot;mod&quot;:&quot;1585297308_001&quot;,&quot;spm&quot;:&quot;1001.2101.3001.6548&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/Yuan_CSDF/article/details/122289287&quot;,&quot;extend1&quot;:&quot;pc&quot;,&quot;ab&quot;:&quot;new&quot;}"><div></div></div> </div>