高效运行GP数据库多表关联的调优技巧 (gp数据库多表关联性能调优)

GP数据库(Greenplum Database)是业界领先的分布式关系型数据库管理系统,其高效的数据压缩、强大的分布式查询和多种工具集使其成为大数据分析和数据仓库领域的首选方案。在GP数据库中,多表关联查询是常见的操作,但是由于数据量大、并行性高的特性,会对查询性能产生影响。本文将介绍一些GP数据库多表关联的调优技巧,以提高查询效率,并减少查询时间。

1. 索引优化

在GP数据库中,索引是提高查询效率的重要手段,因为索引可以快速定位需要查询的数据。因此,我们在进行多表关联查询时,需要对表进行索引优化。可以通过以下方法进行优化:

1) 在关联字段上创建索引

在多表关联查询时,通常会使用关联字段进行连接,此时可以在这些关联字段上创建索引,以加快查询速度。在GP数据库中,可以使用以下语句创建索引:

“`

CREATE INDEX index_name ON table_name (column_name);

“`

2) 使用覆盖索引

覆盖索引是指索引包含了查询所需的所有信息,避免了查询数据的IO操作,从而提高查询效率。在GP数据库中,如果查询的列已经包含在索引中,就可以使用覆盖索引进行查询。可以使用以下语句创建覆盖索引:

“`

CREATE INDEX index_name ON table_name (column_name) INCLUDE (column1, column2…);

“`

2. 分区表优化

在GP数据库中,如果表的数据量很大,会对查询性能产生影响。可以通过分区表的方式,将表分割成多个小表,以减轻每个表的负载。在进行多表关联查询时,可以将分区表进行优化,以提高查询效率。可以通过以下方法进行优化:

1) 使用合适的分区方式

在进行分区表优化时,需要选择合适的分区方式。GP数据库提供了多种分区方式,如范围分区、哈希分区、列表分区等。具体的选择需要根据实际情况进行调整。

2) 使用本地连接

在多表关联查询时,可以使用本地连接方式,即只在同一节点上进行表的连接操作,避免了跨节点的通信,从而提高查询效率。可以通过以下语句指定本地连接:

“`

SELECT /*+NOCROSSJOINS*/ column FROM table1, table2 WHERE table1.column = table2.column;

“`

3. 并行查询优化

在GP数据库中,分布式查询是默认开启的,可以通过并行查询的方式,利用集群中的所有节点进行计算,从而提高查询速度。在进行多表关联查询时,可以通过以下方法进行并行查询优化:

1) 控制并行度

在进行并行查询时,需要控制并行度,即使用多少个节点进行查询。在GP数据库中,可以通过设置max_statement(查询语句的更大并行度)和max_connections(查询的更大连接数)两个参数来控制并行度。通常情况下,建议将max_statement设置为节点数的2-4倍。

2) 并行执行计划查询

并行执行计划查询是一种优化查询过程的方式,它可以让查询在所有节点上同时运行。在GP数据库中,可以通过以下语句执行并行执行计划查询:

“`

EXPLN ANAZE SELECT column1, column2 FROM table1, table2 WHERE table1.column = table2.column;

“`

4. 数据库结构优化

在GP数据库中,还可以通过优化数据库结构,进一步提高多表关联查询的效率。可以通过以下方法进行优化:

1) 压缩数据

对于GP数据库中的大数据量,可以对其进行压缩,以减少存储空间,从而提高查询速度。可以通过以下语句对表进行压缩:

“`

ALTER TABLE table_name SET WITH (COMPRESSION_TYPE=‘type’, COMPRESSION_LEVEL=‘level’);

“`

2) 选择合适的数据类型

在创建数据库表时,需要选择合适的数据类型。数据类型的选择会影响存储空间和查询速度。通常情况下,建议使用与实际数据类型相匹配的数据类型,以提高查询效率。

多表关联查询是GP数据库中常见的操作之一,但是由于数据量大、并行性高的特性,会对查询性能产生影响。在进行多表关联查询时,需要对表进行索引优化、分区表优化、并行查询优化、数据库结构优化等多方面的调优工作,以提高查询效率,并减少查询时间。同时,也需要根据实际情况进行选择和调整,不同的情况需要采用不同的优化方案。

相关问题拓展阅读:

MySQL性能调优 – 你必须了解的15个重要变量

前言:

MYSQL 应该是更流行了 WEB 后端数据库。虽然 NOSQL 最近越来越多的被提到,但是相信大部分架构师还是会选择 MYSQL 来做数据存储。本文作者总结梳理MySQL性能调优的15个重要变量,又不足需要补充的还望大佬指出。

1.DEFAULT_STORAGE_ENGINE

如果你已经在用MySQL 5.6或者5.7,并且你的数据表都是InnoDB,那么表示你已经设置好了。如果没有,确保把你的表转换为InnoDB并且设置default_storage_engine为InnoDB。

为什么?简而言之,因为InnoDB是MySQL(包括Percona Server和MariaDB)更好的存储引擎 – 它支持事务,高并发,有着非常好的性能表现(当配置正确时)。这里有详细的版本介绍为什么

2.INNODB_BUFFER_POOL_SIZE

这个是InnoDB最重要变量。实际上,如果你的主要存储引擎是InnoDB,那么对于你,这个变量对于MySQL是最重要的。

基本上,innodb_buffer_pool_size指定了MySQL应该分配给InnoDB缓冲池多少内存,InnoDB缓冲池用来存储缓存的数据,二级索引,脏数据(已经被更改但没有刷新到硬盘的数据)以及各种内部结构如自适应哈希索引。

根据经验,在一个独立的MySQL服务器应该分配给MySQL整个机器总内存的80%。如果你的MySQL运行在一个共享服务器,或者你想知道InnoDB缓冲池大小是否正确设置,详细请看这里。

3.INNODB_LOG_FILE_SIZE

InnoDB重做日志文件的设置在MySQL社区也叫做事务日志。直到MySQL 5.6.8事务日志默认值innodb_log_file_size=5M是唯一更大的InnoDB性能杀手。从MySQL 5.6.8开始,默认值提升到48M,但对于许多稍繁忙的系统,还远远要低。

根据经验,你应该设置的日志大小能在你服务器繁忙时能存储1-2小时的写入量。如果不想这么麻烦,那么设置1-2G的大小会让你的性能有一个不错的表现。这个变量也相当重要,更详细的介绍请看这里。

当然,如果你有大量的大事务更改,那么,更改比默认innodb日志缓冲大小更大的值会对你的性能有一定的提高,但是你使用的是autocommit,或者你的事务更改小于几k,那还是保持默认的值吧。

4.INNODB_FLUSH_LOG_AT_TRX_COMMIT

默认下,innodb_flush_log_at_trx_commit设置为1表示InnoDB在每次事务提交后立即刷新同步数据到硬盘。如果你使用autocommit,那么你的每一个INSERT, UPDATE或DELETE语句都是一个事务提交。

同步是一个昂贵的操作(特别是当你没有写回缓存时),因为它涉及对硬盘的实际同步物理写入。所以如果可能,并不建议使用默认值。

两个可选的值是0和2:

* 0表示刷新到硬盘,但不同步(提交事务时没有实际的IO操作)

* 2表示不刷新岩困和不同步(也没有实际的IO操作)

所以你如果设置它为0或2,则同步操作每秒执行一次。所以明显的缺点是你可能会丢失上一秒的提交数据。具体来说,你的事务已经提交了,但服务器马上断电了侍枣前,那么你的提交相当于没有发生过。

显示的,对于金融机构,如银行,这是无法忍受的。不过对于大多数网站,可以设置为innodb_flush_log_at_trx_commit=0|2,即使服务器最终崩溃也没有什么大问题。毕竟,仅仅在几年前有许多网站还是用MyISAM,当崩溃时会丢失30s的数据(更不要提那令人抓狂的慢修复进程)。

那么,0和2之间的实际区别是什么?性能明显的差异是可以忽略不计,因为刷新到操作系统缓存的操作是非常快的。所以很明显应该设置为0,老清万一MySQL崩溃(不是整个机器),你不会丢失任何数据,因为数据已经在OS缓存,最终还是会同步到硬盘的。

5.SYNC_BINLOG

已经有大量的文档写到sync_binlog,以及它和innodb_flush_log_at_trx_commit的关系,下面我们来简单的介绍下:

a) 如果你的服务器没有设置从服务器,而且你不做备份,那么设置sync_binlog=0将对性能有好处。

b) 如果你有从服务器并且做备份,但你不介意当主服务器崩溃时在二进制日志丢失一些事件,那么为了更好的性能还是设置为sync_binlog=0.

c) 如果你有从服务器并且备份,你非常在意从服务器的一致性,以及能及时恢复到一个时间点(通过使用最新的一致性备份和二进制日志将数据库恢复到特定时间点的能力),那么你应该设置innodb_flush_log_at_trx_commit=1,并且需要认真考虑使用sync_binlog=1。

问题是sync_binlog=1代价比较高 – 现在每个事务也要同步一次到硬盘。你可能会想为什么不把两次同步合并成一次,想法正确 – 新版本的MySQL(5.6和5.7,MariaDB和Percona Server)已经能合并提交,那么在这种情况下sync_binlog=1的操作也不是这么昂贵了,但在旧的mysql版本中仍然会对性能有很大影响。

6.INNODB_FLUSH_METHOD

将innodb_flush_method设置为O_DIRECT以避免双重缓冲.唯一一种情况你不应该使用O_DIRECT是当你操作系统不支持时。但如果你运行的是Linux,使用O_DIRECT来激活直接IO。

不用直接IO,双重缓冲将会发生,因为所有的数据库更改首先会写入到OS缓存然后才同步到硬盘 – 所以InnoDB缓冲池和OS缓存会同时持有一份相同的数据。特别是如果你的缓冲池限制为总内存的50%,那意味着在写密集的环境中你可能会浪费高达50%的内存。如果没有限制为50%,服务器可能由于OS缓存的高压力会使用到swap。

简单地说,设置为innodb_flush_method=O_DIRECT。

7.INNODB_BUFFER_POOL_INSTANCES

MySQL 5.5引入了缓冲实例作为减小内部锁争用来提高MySQL吞吐量的手段。

在5.5版本这个对提升吞吐量帮助很小,然后在MySQL 5.6版本这个提升就非常大了,所以在MySQL5.5中你可能会保守地设置innodb_buffer_pool_instances=4,在MySQL 5.6和5.7中你可以设置为8-16个缓冲池实例。

你设置后观察会觉得性能提高不大,但在大多数高负载情况下,它应该会有不错的表现。

对了,不要指望这个设置能减少你单个查询的响应时间。这个是在高并发负载的服务器上才看得出区别。比如多个线程同时做许多事情。

8.INNODB_THREAD_CONCURRENCY

InnoDB有一种方法来控制并行执行的线程数 – 我们称为并发控制机制。大部分是由innodb_thread_concurrency值来控制的。如果设置为0,并发控制就关闭了,因此InnoDB会立即处理所有进来的请求(尽可能多的)。

在你有32CPU核心且只有4个请求时会没什么问题。不过想像下你只有4CPU核心和32个请求时 – 如果你让32个请求同时处理,你这个自找麻烦。因为这些32个请求只有4 CPU核心,显然地会比平常慢至少8倍(实际上是大于8倍),而然这些请求每个都有自己的外部和内部锁,这有很大可能堆积请求。

下面介绍如何更改这个变量,在mysql命令行提示符执行:

对于大多数工作负载和服务器,设置为8是一个好开端,然后你可以根据服务器达到了这个限制而资源使用率利用不足时逐渐增加。可以通过show engine innodb status\G来查看目前查询处理情况,查找类似如下行:

9.SKIP_NAME_RESOLVE

这一项不得不提及,因为仍然有很多人没有添加这一项。你应该添加skip_name_resolve来避免连接时DNS解析。

大多数情况下你更改这个会没有什么感觉,因为大多数情况下DNS服务器解析会非常快。不过当DNS服务器失败时,它会出现在你服务器上出现“unauthenticated connections” ,而就是为什么所有的请求都突然开始慢下来了。

所以不要等到这种事情发生才更改。现在添加这个变量并且避免基于主机名的授权。

10.INNODB_IO_CAPACITY, INNODB_IO_CAPACITY_MAX

* innodb_io_capacity:用来当刷新脏数据时,控制MySQL每秒执行的写IO量。

* innodb_io_capacity_max: 在压力下,控制当刷新脏数据时MySQL每秒执行的写IO量

首先,这与读取无关 – SELECT查询执行的操作。对于读操作,MySQL会尽更大可能处理并返回结果。至于写操作,MySQL在后台会循环刷新,在每一个循环会检查有多少数据需要刷新,并且不会用超过innodb_io_capacity指定的数来做刷新操作。这也包括更改缓冲区合并(在它们刷新到磁盘之前,更改缓冲区是辅助脏页存储的关键)。

第二,我需要解释一下什么叫“在压力下”,MySQL中称为”紧急情况”,是当MySQL在后台刷新时,它需要刷新一些数据为了让新的写操作进来。然后,MySQL会用到innodb_io_capacity_max。

那么,应该设置innodb_io_capacity和innodb_io_capacity_max为什么呢?

更好的方法是测量你的存储设置的随机写吞吐量,然后给innodb_io_capacity_max设置为你的设备能达到的更大IOPS。innodb_io_capacity就设置为它的50-75%,特别是你的系统主要是写操作时。

通常你可以预测你的系统的IOPS是多少。例如由8 15k硬盘组成的RAID10能做大约每秒1000随机写操作,所以你可以设置innodb_io_capacity=600和innodb_io_capacity_max=1000。许多廉价企业SSD可以做4,000-10,000 IOPS等。

这个值设置得不完美问题不大。但是,要注意默认的200和400会限制你的写吞吐量,因此你可能偶尔会捕捉到刷新进程。如果出现这种情况,可能是已经达到你硬盘的写IO吞吐量,或者这个值设置得太小限制了吞吐量。

11.INNODB_STATS_ON_METADATA

如果你跑的是MySQL 5.6或5.7,你不需要更改innodb_stats_on_metadata的默认值,因为它已经设置正确了。

不过在MySQL 5.5或5.1,强烈建议关闭这个变量 – 如果是开启,像命令show table status会立即查询INFORMATION_SCHEMA而不是等几秒再执行,这会使用到额外的IO操作。

从5.1.32版本开始,这个是动态变量,意味着你不需要重启MySQL服务器来关闭它。

12.INNODB_BUFFER_POOL_DUMP_AT_SHUTDOWN & INNODB_BUFFER_POOL_LOAD_AT_STARTUP

innodb_buffer_pool_dump_at_shutdown和innodb_buffer_pool_load_at_startup这两个变量与性能无关,不过如果你偶尔重启mysql服务器(如生效配置),那么就有关。当两个都激活时,MySQL缓冲池的内容(更具体地说,是缓存页)在停止MySQL时存储到一个文件。当你下次启动MySQL时,它会在后台启动一个线程来加载缓冲池的内容以提高预热速度到3-5倍。

两件事:

之一,它实际上没有在关闭时复制缓冲池内容到文件,仅仅是复制表空间ID和页面ID – 足够的信息来定位硬盘上的页面了。然后它就能以大量的顺序读非常快速的加载那些页面,而不是需要成千上万的小随机读。

第二,启动时是在后台加载内容,因为MySQL不需要等到缓冲池内容加载完成再开始接受请求(所以看起来不会有什么影响)。

从MySQL 5.7.7开始,默认只有25%的缓冲池页面在mysql关闭时存储到文件,但是你可以控制这个值 – 使用innodb_buffer_pool_dump_pct,建议75-100。

这个特性从MySQL 5.6才开始支持。

13.INNODB_ADAPTIVE_HASH_INDEX_PARTS

如果你运行着一个大量SELECT查询的MySQL服务器(并且已经尽可能优化),那么自适应哈希索引将下你的下一个瓶颈。自适应哈希索引是InnoDB内部维护的动态索引,可以提高最常用的查询模式的性能。这个特性可以重启服务器关闭,不过默认下在mysql的所有版本开启。

这个技术非常复杂,在大多数情况下它会对大多数类型的查询直到加速的作用。不过,当你有太多的查询往数据库,在某一个点上它会花过多的时间等待AHI锁和闩锁。

如果你的是MySQL 5.7,没有这个问题 – innodb_adaptive_hash_index_parts默认设置为8,所以自适应哈希索引被切割为8个分区,因为不存在全局互斥。

不过在mysql 5.7前的版本,没有AHI分区数量的控制。换句话说,有一个全局互斥锁来保护AHI,可能导致你的select查询经常撞墙。

所以如果你运行的是5.1或5.6,并且有大量的select查询,最简单的方案就是切换成同一版本的Percona Server来激活AHI分区。

14.QUERY_CACHE_TYPE

如果人认为查询缓存效果很好,肯定应该使用它。好吧,有时候是有用的。不过这个只在你在低负载时有用,特别是在低负载下大多数是读取,小量写或者没有。

如果是那样的情况,设置query_cache_type=ON和query_cache_size=256M就好了。不过记住不能把256M设置更高的值了,否则会由于查询缓存失效时,导致引起严重的服务器停顿。

如果你的MySQL服务器高负载动作,建议设置query_cache_size=0和query_cache_type=OFF,并重启服务器生效。那样Mysql就会停止在所有的查询使用查询缓存互斥锁。

15.TABLE_OPEN_CACHE_INSTANCES

从MySQL 5.6.6开始,表缓存能分割到多个分区。

表缓存用来存放目前已打开表的列表,当每一个表打开或关闭互斥体就被锁定 – 即使这是一个隐式临时表。使用多个分区绝对减少了潜在的争用。

从MySQL 5.7.8开始,table_open_cache_instances=16是默认的配置。

欢迎做Java的工程师朋友们私信我资料免费获取免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)

其中覆盖了互联网的方方面面,期间碰到各种产品各种场景下的各种问题,很值得大家借鉴和学习,扩展自己的技术广度和知识面。

GBase8s数据库SQL语句性能缓慢从哪个方面入手分析?

在实际的生产运行环境中,很多客户现场都看到开发人员和系统管理人员遇到很多有关于GBase 8s 数据库引起的性能问题,进而被多次问起如何进行GBase 8s 数据库性能调优,

性能优化原则

包括:

性能规划:深入了解应用与数据库的交互特征,确立良好的设计、开发、测试迭代过程,上线前消除模型上的性能瓶胡扰颈。

实例调优:建立性能基准,对比调节数据库、操作系统、存储、网络等的配置,主动监控、消除瓶颈。

SQL 调优:书写高效 SQL,优化相关数据库对象,充分借助优化器,确定更佳执行计划。

性能优化流程

首先执行下面的初始检查:

– 获取直接用户的使用反馈,确定性能目标和范围。

– 获取性能表现好与坏时的操作系统、数据库、应用统计信息。

– 对数据库做一次全面健康检查。

根据收集的信息,以及对应用特性的了解,构建性能概念模型,明确性能瓶颈所在,以及导致性能的根本原因。

– 首先应该排除操作系统、硬件资源造成的瓶颈。

– 然后针对数据库系统性能进行分析

– 必要时,还需要检查应用日志,因为系统性能问题也可能由于应用非 SQL 部分造成瓶颈。

提出一系列针对的优化措施,并根据它们对性能改善的重要程度排序,然后逐一加以实施。不要一次执行所有的优化措施,必须逐条尝试,逐步对比。

通过获取直接用户的反馈验证调节是否已经产生预期的效果,否则,需要重新提炼性能概念模型,直到对应用特性了解进一步准确。

重复上述,直到性能达到目标或由于客观约束无法进一步优化。

常见调优技巧

找到 CPU 占用更高的 SQL

在 syaster 库中执行

select sqx_estcost, sqx_sqlstatement

from syssqexplain

order by sqx_estcost desc

注意:此时看到的仅仅是当前正在执行的 SQL

需要多看几次

onstat 命令

onstat -g act 得到当前正在执行的 SQL

根据 rstcb 列

onstat -u | grep 57c68220

从第三列 sessid 得到 SESSION

onstat -g ses SESSION 即可得到当时正在执行的 SQL

一般多找几个 threads 后,就基本可以确定问题 SQL

得到 SQL 后,利用 set explain on 分析其查询路径,看是否未利用索引,在对大表进行全表扫描,根据需要创建相应索引。

找到全表扫描较多的表及其 SQL

得到全表扫描较多的表

— 系统顺序扫描较裤郑旦多时,被多次顺序扫描的大表,如果有,应该考虑增加索引

select first 5

substr(t.tabname,0,20) tabname,

substr(dbsname,0,10) dbname,

nrows*rowsize*p.seqscans costs,

substr(p.seqscans,0,8) seqscans,

substr(nrows,0,8) nrows

from syaster:sysptprof p , systables t,syaster:sysprofile s

where p.tabname = t.tabname

and p.seqscans > s.value/50

and s.name = ‘seqscans’

–and s.value >and nrows > 2023

order by 3 desc

利用 onstat –g ses 0 –r 5/ onstat –g stm 的输出信息,根据表名,找到可能的 SQL 语句。丛伏由于以上获取 SQL 的办法是有局限的,如果无法获取,建议通过查看应用日志或联系开发人员查看源代码的方式来找到。

利用 set explain on 分析其查询路径,确认是在对表进行全表扫描,根据需要创建相应索引。

关于gp数据库多表关联性能调优的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。


数据运维技术 » 高效运行GP数据库多表关联的调优技巧 (gp数据库多表关联性能调优)