RedShift中关联系统表查询空表被执行的SQL语句时报错求助
RedShift中关联系统表查询空表被执行的SQL语句时报错求助
嗨,我来帮你捋捋这个问题~你现在想找出所有针对空表执行过的查询,但RedShift报错说这种关联子查询模式不支持,这是因为RedShift对某些关联子查询的语法支持有限,尤其是你原来写法里子查询引用外部表z.querytxt的这种模式,很容易触发内部错误。咱们换个写法就能绕开这个限制啦!
先明确下你的核心需求:先筛选出所有行数为0的空表(通过stv_tbl_perm统计行数,结合pg_class的分布风格判断),再找出stl_query里所有访问过这些空表的查询语句。
修改后的可行SQL
我们可以先用CTE(公共表表达式)提前把所有空表筛选出来,再通过JOIN的方式和stl_query关联,这样就避开了不支持的子查询模式:
WITH empty_tables AS ( SELECT b.relname FROM ( SELECT db_id, id, name, MAX(ROWS) rows_all_dist, SUM(ROWS) "rows" FROM stv_tbl_perm GROUP BY db_id, id, name ) a INNER JOIN pg_class b ON b.oid = a.id WHERE CASE WHEN b.reldiststyle = 8 THEN a.rows_all_dist ELSE a.rows END = 0 ) SELECT z.* FROM stl_query z JOIN empty_tables et ON z.querytxt LIKE '%' || et.relname || '%';
一些补充说明
- 为什么这么改?
RedShift对关联子查询的支持不如传统PostgreSQL,用CTE先把空表集合提取出来,再做JOIN的方式更符合RedShift的执行逻辑,不会触发内部错误。 - 关于匹配准确性
用LIKE '%' || et.relname || '%'可能会有少量误判(比如查询文本里刚好出现和表名相同的字符串但不是指该表),如果需要更精准的匹配,可以考虑用正则表达式(比如REGEXP_LIKE(z.querytxt, '\m' || et.relname || '\M'),匹配完整的表名单词),不过得根据你的实际场景调整。 - 长查询的问题
stl_query里的querytxt字段会截断过长的查询,如果你的查询语句很长,可能匹配不到,这时候可以结合stl_querytext表来获取完整的查询文本,关联条件用z.queryid = qt.queryid即可。
备注:内容来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

