Table 条记录的错误计数 (*)
Incorrect Count(*) of Table Records
我正在尝试计算 oracle 中的 table。当我运行一个很简单的计数如:
SELECT COUNT(*) FROM EDW.SCADA_VALUE_HIST; --Returns [114315627]
它 return 的结果(在查询外的括号中)似乎是正确的。现在,当我将过滤条件应用于相同的 table 时,它比 table:
的计数 (*) 多了 return 行
SELECT COUNT(*) FROM EDW.SCADA_VALUE_HIST
WHERE UPDT_VAL_EFF_DTTM <= (SYSDATE-5); --Returns [131416178]
此外,我继续检查了 table 的统计数据(详见 sql 开发人员),它 return 的数量甚至更高 [146436917](我'我知道这不是 100% 准确,但对于这个练习来说应该是合理的)。我没有看到过滤条件如何可以 return 比 table 本身更多的计数行。详情如下:
- 同一个数据库中的查询运行每次10秒内
其他
- table 每 10 分钟插入 ~60k 行
预定作业
- 计划的作业执行一个过程,该过程使用
合并(下)
- UPDT_VAL_EFF_DTTM 是日期字段且此列不可为空
- table总共包含5个索引(Composite Primary key (4 fields) and unique, followed by 4 non-unique indexes
- 在 Oracle 11gr2
上 运行ning
数据库是 运行ning DataGuard 环境,具有 3 个物理备用数据库和 1 个主数据库
create or replace PROCEDURE UPDATE_VALUE_HIST AS
v_date VARCHAR2(16);
g_counter NUMBER(10,0) := 0;
g_insertspeed NUMBER (10,0) := 1000;
g_inserttime NUMBER (10,0) := 20;
BEGIN
BEGIN
MERGE INTO EDW.SCADA_VALUE_HIST SVH
USING
(SELECT
SV.COL1,SV.COL2,SD.COL3,SD.COL4,
SVD.COL5,SVD.COL6,SVD.COL7,SV.COL8,
SVT.COL9 AS VALUE_TYPE_NAME,SV.COL10,SD.COL11,
SYSDATE as UPDT_VAL_EFF_DTTM,'U',SV.COL13,SV.COL14
FROM SCHEMA.T1 SV,
SCHEMA.T2 SVD,
SCHEMA.T3 SVT,
SCHEMA.T4 SD
WHERE SV.FIELD1= SVD.FIELD1
AND SVD.FIELD2= SVT.FIELD2
AND SD.FIELD3= SVD.FIELD3
AND SV.FIELD4 IS NOT NULL) B
ON (
SVH.FIELD1= B.FIELD1
AND SVH.FIELD2= B.FIELD2
AND SVH.FIELD3= B.FIELD3
AND SVH.FIELD4 = B.FIELD4
)
WHEN NOT MATCHED
THEN
INSERT (COL1, COL2, COL3, COL4, COL5, COL6, COL7, COL8,
COL9, COL10, COL11, SYSDATE, 'U', COL13, COL14);
COMMIT;
END;
END;
我试过谷歌搜索几次,但计数帖子中的大部分错误都与连接和过滤条件有关。这对我来说非常运行ge。
编辑:
解释第一次查询的计划:
SELECT 语句 -> 排序(聚合)-> 索引(对对象 PK 进行快速全面扫描)
基数:1 -> 1 -> 146436917
费用:85031
解释第二次查询的计划:
SELECT -> 排序(聚合) -> 索引(对对象不同索引的快速完整扫描比 PK(过滤谓词索引)) -> 过滤谓词 -> UPDT_VAL_EFF_DTTM
基数:1 -> 1 -> 131379677
费用:105341
当我看到这种情况发生时(只有一两次),那是因为索引已损坏。我们重建或删除并重新创建索引,问题就消失了。
这只是一个轶事,并没有解释发生了什么或为什么。但在您浪费大量时间处理 Oracle 支持之前,您需要先尝试这些 "bad" 解决方案。现在花 5 分钟重建它,您可能会避免以后几天的调查。如果问题不再发生,那么根本原因并不重要。
我正在尝试计算 oracle 中的 table。当我运行一个很简单的计数如:
SELECT COUNT(*) FROM EDW.SCADA_VALUE_HIST; --Returns [114315627]
它 return 的结果(在查询外的括号中)似乎是正确的。现在,当我将过滤条件应用于相同的 table 时,它比 table:
的计数 (*) 多了 return 行SELECT COUNT(*) FROM EDW.SCADA_VALUE_HIST
WHERE UPDT_VAL_EFF_DTTM <= (SYSDATE-5); --Returns [131416178]
此外,我继续检查了 table 的统计数据(详见 sql 开发人员),它 return 的数量甚至更高 [146436917](我'我知道这不是 100% 准确,但对于这个练习来说应该是合理的)。我没有看到过滤条件如何可以 return 比 table 本身更多的计数行。详情如下:
- 同一个数据库中的查询运行每次10秒内 其他
- table 每 10 分钟插入 ~60k 行 预定作业
- 计划的作业执行一个过程,该过程使用 合并(下)
- UPDT_VAL_EFF_DTTM 是日期字段且此列不可为空
- table总共包含5个索引(Composite Primary key (4 fields) and unique, followed by 4 non-unique indexes
- 在 Oracle 11gr2 上 运行ning
数据库是 运行ning DataGuard 环境,具有 3 个物理备用数据库和 1 个主数据库
create or replace PROCEDURE UPDATE_VALUE_HIST AS v_date VARCHAR2(16); g_counter NUMBER(10,0) := 0; g_insertspeed NUMBER (10,0) := 1000; g_inserttime NUMBER (10,0) := 20; BEGIN BEGIN MERGE INTO EDW.SCADA_VALUE_HIST SVH USING (SELECT SV.COL1,SV.COL2,SD.COL3,SD.COL4, SVD.COL5,SVD.COL6,SVD.COL7,SV.COL8, SVT.COL9 AS VALUE_TYPE_NAME,SV.COL10,SD.COL11, SYSDATE as UPDT_VAL_EFF_DTTM,'U',SV.COL13,SV.COL14 FROM SCHEMA.T1 SV, SCHEMA.T2 SVD, SCHEMA.T3 SVT, SCHEMA.T4 SD WHERE SV.FIELD1= SVD.FIELD1 AND SVD.FIELD2= SVT.FIELD2 AND SD.FIELD3= SVD.FIELD3 AND SV.FIELD4 IS NOT NULL) B ON ( SVH.FIELD1= B.FIELD1 AND SVH.FIELD2= B.FIELD2 AND SVH.FIELD3= B.FIELD3 AND SVH.FIELD4 = B.FIELD4 ) WHEN NOT MATCHED THEN INSERT (COL1, COL2, COL3, COL4, COL5, COL6, COL7, COL8, COL9, COL10, COL11, SYSDATE, 'U', COL13, COL14); COMMIT; END; END;
我试过谷歌搜索几次,但计数帖子中的大部分错误都与连接和过滤条件有关。这对我来说非常运行ge。
编辑:
解释第一次查询的计划:
SELECT 语句 -> 排序(聚合)-> 索引(对对象 PK 进行快速全面扫描)
基数:1 -> 1 -> 146436917 费用:85031
解释第二次查询的计划:
SELECT -> 排序(聚合) -> 索引(对对象不同索引的快速完整扫描比 PK(过滤谓词索引)) -> 过滤谓词 -> UPDT_VAL_EFF_DTTM
基数:1 -> 1 -> 131379677 费用:105341
当我看到这种情况发生时(只有一两次),那是因为索引已损坏。我们重建或删除并重新创建索引,问题就消失了。
这只是一个轶事,并没有解释发生了什么或为什么。但在您浪费大量时间处理 Oracle 支持之前,您需要先尝试这些 "bad" 解决方案。现在花 5 分钟重建它,您可能会避免以后几天的调查。如果问题不再发生,那么根本原因并不重要。