一文为你详解Unique SQL原理和应用
摘要:以一定的算法结合解析树中的各结点,计算出来一个整数值,用来唯一标识这一类SQL,这个整数值被称为Unique SQL ID,Unique SQL ID相同的SQL语句属于同一个“Unique SQL”。
1、什么是Unique SQL
用户执行SQL语句时,每一个SQL语句文本都会进入解析器(Parser),生成“解析树”(parse tree)。遍历解析树中各个结点,忽略其中的常数值,以一定的算法结合树中的各结点,计算出来一个整数值,用来唯一标识这一类SQL,这个整数值被称为Unique SQL ID,Unique SQL ID相同的SQL语句属于同一个“Unique SQL”。
例如,用户先后输入如下两条SQL语句:
select * from t1 where id = 1;
select * from t1 where id = 2;
这两条SQL语句除了过滤条件的常数值不同,其他地方都相同,由此生成的解析树的拓扑结构完全相同,故Unique SQL ID也相同。因此两条语句属于如下同一个Unique SQL:
select * from t1 where id = ?;
GaussDB内核会对所有上面形式的SQL语句汇总统计信息,通过视图呈现给用户。通过这种方式,可以排除一些无关的常量值的干扰,获得某一类SQL语句的统计数据,为性能分析和问题定位提供数值依据。
注意,对于Unique SQL ID的计算,只会排除常数值,而不会排除其他的差异。例如,SQL语句“select * from t2 where id = 1;” 与上面的SQL不属于同一个Unique SQL,不同用户,从不同的CN节点执行的相同的SQL语句也不属于同一个Unique SQL。
2、Unique SQL如何统计
收到SQL请求后,GaussDB内核首先算出其Unique SQL ID。如果该Unique SQL ID已存在,则直接更新相关的统计信息。如果不存在,首先创建一个Unique SQL,然后再更新统计信息,如下图所示:

Unique SQL的统计信息包括执行次数,响应时间,Cache/IO数量,行活动和时间分布等信息,可以通过如下两个视图查询:
- gs_instr_unique_sql
- pgxc_instr_unique_sql
前者显示当前CN(Coordinator Node)节点(执行当前SQL命令的节点)上的Unique SQL信息,后者显示系统中所有CN节点上的Unique SQL信息。两个视图的格式相同,均由下表中的字段组成:

3、如何使用Unique SQL
使用Unique SQL功能需要打开以下变量开关:
- enable_resource_check(默认为on)
- track_counts(默认为on,影响行活动和Cache/IO相关字段)
此外还需要将instr_unique_sql_count设为正整数。该变量默认为0,且不能在gsql会话中修改,需要通过SIGHUP的方式设置,例如:
gs_guc reload -Z coordinator -D /path/to/coordinator1/ -c "instr_unique_sql_count=20" > /dev/null
instr_unique_sql_count参数决定了系统收集的unique sql的数量。当收集的unique数量达到这个数后,新的sql不再被收集。如果将该数值改大,原有的unique sql信息保留,同时开始收集新的unique sql。如果将该数值改小,则会清空当前CN节点所有已收集的unique sql信息,然后开始收集新的unique sql。
设置好上述变量后,Unique sql统计视图可以像普通视图一样查询,例如:
postgres=# select node_name,query,n_calls from pgxc_instr_unique_sql;
node_name | query | n_calls
--------------+------------------------------------------------------------+---------
coordinator2 | select node_name,query,n_calls from pgxc_instr_unique_sql; | 0
(1 row)
系统函数reset_instr_unique_sql可以清理unique sql信息,该函数有3个参数,含义如下:
1. scope:如果为"GLOBAL",则清除所有CN节点上的数据;如果为"LOCAL",只清空当前CN上的数据。
2. type:如果为“ALL”,则清除所有数据;如果为"BY_USERID",只清除指定用户的unique SQL;如果为"BY_CNID",只清除指定CN的unique SQL。
3. value:如果type=“ALL”,该参数无意义;如果type="BY_USERID",该参数为指定用户的ID,如果type="BY_CNID",该参数为指定CN的ID。
例如:
postgres=# select reset_instr_unique_sql('global','all',0);
reset_instr_unique_sql
------------------------
t
(1 row)
此外,如果数据库进程重启,也会导致之前收集的unique SQL信息被清空。
4、用Unique SQL辅助定位问题
unique sql视图提供了丰富的信息,用户可以根据需要选取对自己有帮助的信息使用。本节针对客户在生产环境中遇到的实际情况,举例说明几种该视图的使用方法,可供性能优化参考。
4.1 查询异常的行活动导致的磁盘争用
异常的行活动可能引起磁盘争用,导致业务运行缓慢。通过查看扫描的行数、返回的函数、更改的行数等指标的波动情况,可以发现异常的行活动,帮助定位原因。
postgres=# select sum(n_returned_rows) n_returned_rows, sum(n_tuples_fetched) n_tuples_fetched,
sum(n_tuples_returned) n_tuples_returned, sum(n_tuples_inserted) n_tuples_inserted,
sum(n_tuples_updated) n_tuples_updated, sum(n_tuples_deleted) n_tuples_deleted from pgxc_instr_unique_sql;
n_returned_rows | n_tuples_fetched | n_tuples_returned | n_tuples_inserted | n_tuples_updated | n_tuples_deleted
-----------------+------------------+-------------------+-------------------+------------------+------------------
234 | 0 | 0 | 0 | 0 | 0
(1 row)
4.2 查询Top SQL对资源的占用情况
可以基于执行时间、CPU时间、扫描行数、物理读/逻辑读等指标,对unique SQL视图中的SQL语句进行排序,找出占用资源最多的那些SQL语句,有针对性地其分析对性能的影响和原因,帮助查找和定位问题。例如,
- 按SQL执行时间顺序或倒序排序:
SELECT user_name, unique_sql_id, query, total_elapse_time FROM pgxc_instr_unique_sql ORDER BY total_elapse_time ASC 或 DESC;
- 按SQL执行占用CPU时间进行顺序或倒序排序:
SELECT user_name, unique_sql_id, query, cpu_time FROM pgxc_instr_unique_sql ORDER BY cpu_time ASC 或 DESC;
- 按SQL顺序扫描行数顺序或倒序排序:
SELECT user_name, unique_sql_id, query, n_tuples_returned FROM pgxc_instr_unique_sql ORDER BY n_tuples_returned ASC 或 DESC;
- 按SQL总扫描行进行顺序或倒序排序:
SELECT user_name, unique_sql_id, query, n_tuples_fetched + n_tuples_returned FROM pgxc_instr_unique_sql ORDER BY n_tuples_fetched + n_tuples_returned ASC 或 DESC;
- 按SQL执行执行器时间进行顺序或倒序排序:
SELECT user_name, unique_sql_id, query, execution_time FROM pgxc_instr_unique_sql ORDER BY execution_time ASC 或 DESC;
- 按SQL执行物理读次数进行顺序或倒序排序:
SELECT user_name, unique_sql_id, query, n_blocks_fetched FROM pgxc_instr_unique_sql ORDER BY n_blocks_fetched ASC 或 DESC;
- 按SQL执行逻辑读次数进行顺序或倒序排序:
SELECT user_name, unique_sql_id, query, n_blocks_hit FROM pgxc_instr_unique_sql ORDER BY n_blocks_hit ASC 或 DESC;
4.3 查询逻辑读/物理读数量
逻辑读/物理读过多可能导致SQL语句占用较多的CPU时间。通过查询unique SQL视图可以得到sql语句逻辑/物理读数据块的数量,辅助判断响应过慢的原因:
- 查询物理读块数量:
SELECT n_blocks_fetched FROM pgxc_instr_unique_sql;
- 查询逻辑读块数量:
SELECT n_blocks_hit FROM pgxc_instr_unique_sql;
4.4 诊断内存配额不足导致性能低下
如果数据库缓冲区设置得太小,会导致每个SQL语句执行的结果不能被缓存,当前SQL执行完毕如果有其他SQL执行就会把内存中上一个或上几个SQL缓存的执行结果挤出去,下一轮如果当前这个SQL再次执行时候又需要从磁盘进行物理IO读取数据,而不能直接从缓存中获取数据,进而导致SQL执行性能较差。
缓冲区配额是否足够大,可以通过命中率来判断。缓冲区命中率=n_blocks_hit/n_blocks_fetched,可以通过查询unique SQL来诊断是否存在内存配额不足的问题:
SELECT (n_blocks_hit/ n_blocks_fetched) AS hit_ratio from pgxc_instr_unique_sql;
一文为你详解Unique SQL原理和应用的更多相关文章
- mybatis 详解------动态SQL
mybatis 详解------动态SQL 目录 1.动态SQL:if 语句 2.动态SQL:if+where 语句 3.动态SQL:if+set 语句 4.动态SQL:choose(when,o ...
- CSS布局之脱离文档流详解——浮动、绝对定位脱离文档流的区别
1.代码 (1)示例代码1 <!DOCTYPE html> <html lang="zh"> <head> <meta charset=& ...
- 深入解析ThreadLocal 详解、实现原理、使用场景方法以及内存泄漏防范 多线程中篇(十七)
简介 从名称看,ThreadLocal 也就是thread和local的组合,也就是一个thread有一个local的变量副本 ThreadLocal提供了线程的本地副本,也就是说每个线程将会拥有一个 ...
- Java 详解 JVM 工作原理和流程
Java 详解 JVM 工作原理和流程 作为一名Java使用者,掌握JVM的体系结构也是必须的.说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成:Java ...
- MYSQL之数据库初识、安装详解、sql语句基本操作
目录 MYSQL之数据库初识及安装详解 1.什么是数据库? 1.什么是数据?(data) 2.什么是数据库?(databases,简称DB) 2.为什要用数据库? 3.什么是数据库管理系统?(Data ...
- Linux : select()详解 和 实现原理【转】
转自:http://blog.csdn.net/huntinux/article/details/39289317 原文:http://blog.csdn.net/boboiask/article/d ...
- 分布式大牛详解Zookeeper底层原理
很多学员都在反馈,说zk很难学,学的不是很明白,在这里,我继续带着大家详解一遍Zookeeper 首先zk是什么呢首先肯定是一个个分布式服务框架,是Apache Hadoop 的一个子项目,它主要是用 ...
- Java web Cookie详解(持久化+原理详解+共享问题+设置中文+发送多个Cookie)
Java web Cookie详解 啥是cookie? 查询有道词典得: web和饼干有啥关系? 这个谜底等等来为大家揭晓 会话技术 web中的会话技术类似于生活中两个人聊天,不过web中的会话指的是 ...
- CDN技术详解及实现原理
CDN技术详解 一本好的入门书是带你进入陌生领域的明灯,<CDN技术详解>绝对是带你进入CDN行业的那盏最亮的明灯.因此,虽然只是纯粹的重点抄录,我也要把<CDN技术详解>的精 ...
- Cross-Origin Resource Sharing(CORS)详解,CORS详解,CORS原理分析
Keywords CORS, 跨域,JS跨域调用,Ajax CORS 跨域,跨域详解,CORS跨域原理 Cross-Origin Resource Sharing详解 Cross-Origin Res ...
随机推荐
- Speex详解(2019年09月25日更新)
Speex详解 整理者:赤勇玄心行天道 QQ号:280604597 微信号:qq280604597 QQ群:511046632 博客:www.cnblogs.com/gaoyaguo 大家有什么不明白 ...
- 文心一言 VS 讯飞星火 VS chatgpt (119)-- 算法导论10.3 4题
四.用go语言,我们往往希望双向链表的所有元素在存储器中保持紧凑,例如,在多数组表示中占用前m 个下标位置.(在页式虚拟存储的计算环境下,即为这种情况.)假设除指向链表本身的指针外没有其他指针指向该链 ...
- docker简单部署
docker 安装部署-yun yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docke ...
- 关于长链剖分的数组实现 | CF1009F Dominant Indices
请容许我不理解一下为什么这题题解几乎全都是指针实现/kk 其实长链剖分是可以直接用数组来写的. 考虑朴素 DP.设 \(f_{u,i}\) 表示以点 \(u\) 为根的子树中与点 \(u\) 距离为 ...
- Chromium Canvas工作流
blink 中实现了2种 canvas,分别是 blink::HTMLCanvasElement 和 blink::OffscreenCanvas ,前者对应 html/dom 中的 canvas,后 ...
- 20.7 OpenSSL 套接字SSL加密传输
OpenSSL 中的 SSL 加密是通过 SSL/TLS 协议来实现的.SSL/TLS 是一种安全通信协议,可以保障通信双方之间的通信安全性和数据完整性.在 SSL/TLS 协议中,加密算法是其中最核 ...
- 文心一言 VS 讯飞星火 VS chatgpt (132)-- 算法导论11.2 4题
四.用go语言,说明在散列表内部,如何通过将所有未占用的槽位链接成一个自由链表,来分配和释放元素所占的存储空间.假定一个槽位可以存储一个标志.一个元素加上一个或两个指针.所有的字典和自由链表操作均应具 ...
- two-pointer 算法
介绍 双指针算法是一种通过设置两个指针不断进行单向移动来解决问题的算法. 它包含两种形式: 两个指针分别指向不同的序列.比如:归并排序的合并过程. 两个指针指向同一个序列.比如:快速排序的划分过程. ...
- SQL INSERT INTO 语句详解:插入新记录、多行插入和自增字段
SQL INSERT INTO 语句用于在表中插入新记录. INSERT INTO 语法 可以以两种方式编写INSERT INTO语句: 指定要插入的列名和值: INSERT INTO 表名 (列1, ...
- 平台工程时代的 Kubernetes 揭秘:2023年生产状况报告深度剖析
Kubernetes 在生产环境中的复杂性已经成为常态,在2023年这个平台工程盛行的时代,容器管理的最大亮点可能在于其灵活性,然而在运维政策和治理等方面仍然存在诸多挑战.八年过去了,在生产环境中使用 ...