Return 计数值为 0 的 table_name 和 partition_name
Return the table_name and partition_name whose count have a value of 0
我正在尝试编写一个查询,其中 return table_name 和 partition_name 的分区计数值为 0。
我得到以下查询 return 表的 SELECT COUNT() 及其分区:
SELECT 'SELECT COUNT(*) FROM ' || TABLE_NAME || ' PARTITION (' || PARTITION_NAME || ');'
FROM user_tab_partitions
ORDER BY table_name;
这些 SELECT return:
SELECT COUNT(*) FROM A5109713 PARTITION (PT5109713_201210);
SELECT COUNT(*) FROM A5109713 PARTITION (PT5109713_201104);
SELECT COUNT(*) FROM A5109713 PARTITION (PT5109713_201301);
最后一个是唯一的return数据:
COUNT(*) |
2430276 |
我需要的是return那些table_name和partition_name没有数据的查询。像这样:
TABLE_NAME | PARTITION_NAME
A5109713 | PT5109713_201210
A5109713 | PT5109713_201104
这种使用动态 SQL 的方法实施起来很重,执行起来也很慢(因为您需要手动计算每个分区中的行数)。此外,您现在发现自己需要一些额外的逻辑,这将需要更多 PL/SQL 代码。
系统视图 user_tab_partitions
具有名为 num_rows
的列,即 documented as:分区中的行数 。它包含的信息的可靠性取决于您的统计数据的新鲜度。
因此,如果您的统计信息是最新的,那么您可以直接从视图中获取您正在寻找的信息:
select table_name, partition_name
from user_tab_partitions
where num_rows = 0
order by table_name, partition_name
我想要这样的程序:
DECLARE
r INTEGER;
cur sys_refcursor;
BEGIN
FOR aPart IN (SELECT TABLE_NAME, PARTITION_NAME FROM USER_TAB_PARTITIONS ORDER BY TABLE_NAME, PARTITION_POSITION) LOOP
OPEN cur FOR 'SELECT ROWNUM FROM '||aPart.TABLE_NAME||' PARTITION ('||aPart.PARTITION_NAME||') WHERE ROWNUM <= 1';
FETCH cur INTO r;
IF cur%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE(aPart.TABLE_NAME||CHR(9)||aPart.PARTITION_NAME);
end if;
close cur;
END LOOP;
END;
我不会依赖 NUM_ROWS
的看法 USER_TAB_PARTITIONS
因为它包含的信息的可靠性取决于您的统计数据的新鲜度。
出于性能原因,我使用 SELECT ROWNUM FROM ... WHERE ROWNUM <= 1;
而不是 COUNT(*)
。其实你对总行数不感兴趣,你只想知道它们是否大于0。
在最坏的情况下 COUNT(*)
运行 FULL-TABLE 扫描,这比只读取第一条记录要慢得多。
我正在尝试编写一个查询,其中 return table_name 和 partition_name 的分区计数值为 0。
我得到以下查询 return 表的 SELECT COUNT() 及其分区:
SELECT 'SELECT COUNT(*) FROM ' || TABLE_NAME || ' PARTITION (' || PARTITION_NAME || ');'
FROM user_tab_partitions
ORDER BY table_name;
这些 SELECT return:
SELECT COUNT(*) FROM A5109713 PARTITION (PT5109713_201210);
SELECT COUNT(*) FROM A5109713 PARTITION (PT5109713_201104);
SELECT COUNT(*) FROM A5109713 PARTITION (PT5109713_201301);
最后一个是唯一的return数据:
COUNT(*) |
2430276 |
我需要的是return那些table_name和partition_name没有数据的查询。像这样:
TABLE_NAME | PARTITION_NAME
A5109713 | PT5109713_201210
A5109713 | PT5109713_201104
这种使用动态 SQL 的方法实施起来很重,执行起来也很慢(因为您需要手动计算每个分区中的行数)。此外,您现在发现自己需要一些额外的逻辑,这将需要更多 PL/SQL 代码。
系统视图 user_tab_partitions
具有名为 num_rows
的列,即 documented as:分区中的行数 。它包含的信息的可靠性取决于您的统计数据的新鲜度。
因此,如果您的统计信息是最新的,那么您可以直接从视图中获取您正在寻找的信息:
select table_name, partition_name
from user_tab_partitions
where num_rows = 0
order by table_name, partition_name
我想要这样的程序:
DECLARE
r INTEGER;
cur sys_refcursor;
BEGIN
FOR aPart IN (SELECT TABLE_NAME, PARTITION_NAME FROM USER_TAB_PARTITIONS ORDER BY TABLE_NAME, PARTITION_POSITION) LOOP
OPEN cur FOR 'SELECT ROWNUM FROM '||aPart.TABLE_NAME||' PARTITION ('||aPart.PARTITION_NAME||') WHERE ROWNUM <= 1';
FETCH cur INTO r;
IF cur%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE(aPart.TABLE_NAME||CHR(9)||aPart.PARTITION_NAME);
end if;
close cur;
END LOOP;
END;
我不会依赖 NUM_ROWS
的看法 USER_TAB_PARTITIONS
因为它包含的信息的可靠性取决于您的统计数据的新鲜度。
出于性能原因,我使用 SELECT ROWNUM FROM ... WHERE ROWNUM <= 1;
而不是 COUNT(*)
。其实你对总行数不感兴趣,你只想知道它们是否大于0。
在最坏的情况下 COUNT(*)
运行 FULL-TABLE 扫描,这比只读取第一条记录要慢得多。