本文档介绍了弹性并行查询(Elastic Parallel Query)的常见问题。
PolarDB读写集群地址是否可以通过hint开启并行查询?
优先推荐您在PolarDB控制台的集群地址配置页面开启并行查询。如果您希望在SQL语句级别生效,可以通过/*+ PARALLEL(n) */
或者 /*+ SET_VAR(max_parallel_degree=n) */
设置查询的并行度为n
,但两种设置方式会有所区别:
当使用
/*+ PARALLEL(n) */
时,会强制开启并行查询,不考虑查询是否已经分发到RW节点,也不考虑查询所涉及的数据量。当使用
/*+ SET_VAR(max_parallel_degree=n) */
时,是否并行取决于查询是否路由到RO节点,以及优化器所评估的查询代价和表数据量。
更多详情请参见通过Hint控制。
在SQL语句中通过hint设定并行参数与控制台上设置是否有冲突?
没有冲突,通过hint指定的参数仅对当前SQL生效,优先级高于控制台上的全局设置并行参数。但建议您在PolarDB控制台基本信息的集群地址配置页面设置并行参数,具体操作请参见配置数据库代理。
小规格的集群例如通用版4核8 GB,可以使用并行查询吗?
对于小规格集群(核数小于8),默认不会开启并行查询。如果确定RO节点有较多空闲的计算资源,可以根据负载情况开启并行查询,也能达到提升效果,但不建议并行度超过该核数。此外您需要调高max_parallel_workers
的取值来放开限制,建议该参数设置为CPU核数的2倍。更多信息请参见并行度控制策略。
PolarDB单表上亿条数据,采用分区表还是直接使用并行查询更合适?
并行查询功能和分区表功能并不冲突,分区的益处是便于管理数据。并行查询的目的在于加速复杂查询的处理效率,并且无论是否使用分区表都可以使用并行查询,并行查询也支持在分区表上使用。关于分区表和并行查询的更多介绍请参见分区表和弹性并行查询。
连接PolarDB的读写分离地址能使用并行查询吗?
可以。
PolarDB如果通过扩容增加了CPU核数,并行查询会自动把线程分配到新增加的CPU核数上吗?
是的,PolarDB自动的把线程分配到新增加的CPU核数上。
不同集群类型和内核版本的并行查询存在差异吗?
集群类型不同,硬件资源会存在差异(如CPU核数)会影响到并行查询的并行度。而PolarDB的内核版本不同,会影响并行查询的使用。5.6和5.7版本不支持并行查询,8.0支持并行查询。
PolarDB集群需要开启并行查询功能,但是没有找到max_parallel_degree这个参数,如何处理?
首先要确认当前集群版本是否支持并行查询,PolarDB集群版本需为PolarDB MySQL版8.0版本且修订版本需满足如下条件:
单机并行:8.0.1.0.5或以上,8.0.2.1.4.1或以上。
多机并行:8.0.2.2.6或以上。
如需要开启并行,建议在控制台基本信息的集群地址区域,单击编辑配置,打开编辑地址配置页面,设置并行度参数及并行引擎,开启并行查询。具体操作请参见配置数据库代理的并行查询说明。
PolarDB集群group by/order by涉及的数据量非常大导致临时表很大,如何处理?
这个问题的关键在于查询产生的临时表量过高过密集,您可以通过开启多机并行查询来解决这个问题,开启多机并行查询的操作请参见使用说明。
开启并行查询时,不同的集群规格并行度设置为多少合适?
一般建议并行度的初始值设置为集群CPU核数的1/4,比如规格是16核,建议初始并行度设置为4。如果开启并行查询后,集群业务负载不高,可适当调高并行度。
对于8.0.1版本,只支持单机并行,一般不建议并行度超过CPU核数的1/2。
对于8.0.2版本,支持跨节点多机并行。如果有多个RO节点,可以适当调大单节点的并行度。例如有2个8核的RO节点,可以将并行度设置为4,则实际会启动8个线程在2个节点上执行单条查询,获得更优的查询加速。
PolarDB开启并行查询,并行度如何根据负载进行调整?
例如集群的节点CPU是16核,初始并行度设置为4。开启并行查询后,在几个完整的业务周期内观察集群负载的变化,如果集群负载还有较多的空闲,可适当将并行度调整为6,再重新进行观察,逐步调整并行度。
集群负载是否空闲,主要看集群的CPU和内存使用率,CPU使用率不超过50%并且内存使用率不超过80%则认为集群负载空闲。在8.0.2版本集群上,单条查询可以分发到多个节点执行,进一步提升并行能力和查询效率,因此可以设置更大的单节点并行度。
并行度设置是否越大越好,是否有负面影响?
并行查询的基本原理是有效利用多核CPU并发处理来加速查询,开启并行查询会占用更多的计算资源,并行度设置的过大可能导致集群负载偏高,一般建议不超过CPU核数的1/4。另外并行度超过CPU的核数是没有意义的,当集群有多个RO节点时,可以在8.0.2版本上开启多机并行,将单节点并行度放大到多个节点上。
开启并行查询后,所有查询都会被并行加速吗?
并不是所有查询都采用并行方式执行,如下三种情况的查询不会并行:
不支持并行的查询,详情请参见并行查询的使用限制。
查询扫描的数据量或代价未达到并行的阈值,阈值设置参数为records_threshold_for_parallelism和cost_threshold_for_parallelism。
当集群资源负载过高时,查询将不再采用并行查询,详情请参见系统资源使用限制。
parallel_degree_policy参数的取值REPLICA_AUTO和TYPICAL的区别?
REPLICA_AUTO的含义是主节点禁止并行,只允许只读节点并行,根据实时资源负载决策是否使用并行;TYPICAL的含义是允许主节点并行,且是否采用并行时不考虑实时负载的因素。
开启并行查询后,如何确定一个查询是否并行?
使用explain
可以查看查询是否并行。如果SQL查询使用了并行查询,在Extra信息中可以看到Parallel Scan (4 workers)
的信息,详情请参见EXPLAIN查询语句。
如果集群地址为可读可写模式,explain
语句默认路由到主节点执行,因为主节点默认不开启并行查询。通过explain
查看的计划不准确,需要增加Hint才能准确看到并行计划,例如:/* FORCE_SLAVE */ explain select count(*) from t1
。
一个SQL查询使用explain来查看已使用并行查询,但查询性能并没有提升或提升不明显是怎么原因?
并行加速效果不明显的原因有如下几种:
通过
explain /*+ FORCE_SLAVE() */ SELECT ...
查看执行计划,判断SQL是否完成了执行计划,查看是否使用了并行查询,在explain中如看到Parallel scan
字段,则表明使用了并行查询。并行查询的基本原理是将一个大查询任务拆解成多个小的查询任务并发执行,但如果查询的表的实际数据量较少,不能拆分为更多的子任务。例如并行度设置的是4,但因为查询的数据量较少,最多只拆分出了2个子任务,这种情况并行加速的效果就取决于最大拆分的子任务数。如果内核版本是8.0.1,您可以通过
Parallel scan
字段后面的workers数量判断是否生成了足够的并行线程;如果内核版本是8.0.2,您可以通过with parallel partitions
字段后面的数值判断是否切分了足够的分片数量,当分片数量比max_parallel_degree小时,会导致部分worker空闲而降低查询性能。并行查询的执行分为1个leader线程和多个worker线程,worker线程负责并行计算,leader线程负责汇聚结果并返回。一个查询语句中并不是所有算子都能下推到worker上执行,部分算子会留在leader上执行,如果留在leader上执行的算子比较耗时,就会有单线程的瓶颈,导致并行加速不理想。
集群资源负载不稳定,使用explain查看时资源负载并不高,可以执行并行查询。但当您真正执行并行查询时,遇到集群负载较高,并行查询被限制回退为串行执行。这种情况可以通过资源负载的性能监控,查看是否有资源负载抖动的情况。
PolarDB在使用offset或limit查询,且不加上排序条件时,并行查询的结果为什么不稳定?
如果不加上排序条件,从查询语义上讲,查询结果不稳定是预期的。但如果不开启并行查询时结果是稳定的,而开启并行查询后结果不稳定。对于这个问题PolarDB并不能完全保证查询结果是稳定的,只有查询总是命中同一个索引的情况下,查询结果才是稳定的;如果同一个查询命中的索引不同,PolarDB并不能保证查询结果的稳定性。
如果主节点也开启并行查询,会有什么影响?
使用并行查询会消耗掉一定的系统资源,因此在主节点也开启并行查询会使得主节点负载压力变大。系统默认不在主节点上开启并行查询,如果业务可以确保写业务量较低或写入吞吐要求不高,则也可以在主节点上开启并行查询,并且需要设置并行度和parallel_degree_policy参数为AUTO
或TYPICAL
。
开启并行查询并打开innodb_adaptive_hash_index参数时,查询性能为什么变差?
并行查询导致更多线程频繁查询同一颗btree,构建的hash index会有反复失效和并发争抢问题,查询性能是可能变差的。详情请参考概述。