我有一种情况我找不到解释,就在这里。(我将使用假设信息,因为原始信息非常大。)
我有一张桌子,让我们说:
table_a
-------------
name
last name
dept
status
notes
并且这个表有一个insert触发器,它对info做了大量的验证,根据验证的结果来改变新记录的status字段,其中一些验证是:
- check for the name existing in a dictionary
- check for the last name existing in a dictionary
- check that fields (name,last name,dept) aren't already inserted in table_b
- ... and so on
问题是,如果我通过查询在表上插入,比如
insert into table_a
(name,last_name,dept,status,notes)
values
('john','smith',1,0,'new');
完成所有验证过程、更新状态字段并在表中插入记录只需要 173 毫秒。(验证过程通过索引进行所有搜索)
但是如果我通过 SQLloader 尝试这个,读取一个包含 5000 条记录的文件,验证和插入 149 条记录需要大约 40 分钟(当然我杀了它......)
所以我尝试加载禁用触发器的数据(以检查速度),我得到它像所有记录一样在不到 10 秒的时间内加载。
所以我的问题是,我能做些什么来改进这个过程?我唯一的理论是我可能会使数据库饱和,因为它加载速度如此之快并启动了许多触发器实例,但我真的不知道。
我的目标是加载大约 60 个包含信息的文件,并通过触发器中的过程验证它们(尽管愿意尝试其他选项)。
我真的很感激你能提供的任何帮助!
补充------------------------------------------------- --------------------------------
感谢您的回答,现在我将阅读所有相关信息,现在希望您能在这部分帮助我。让我解释一下我需要的一些功能(我使用了触发器,因为我想不出其他任何东西)
所以表数据带有这个(重要的)字段:
pid name lastname birthdate dept cicle notes
数据是这样的
name lastname birthdate dept
现在,触发器对数据执行此操作:
调用函数来计算 pid(根据姓名、姓氏和生日用算法计算)
调用一个函数来检查字典上的名字(那是因为在我的字典中我有一个名字,这意味着如果一个人被命名为 john aaron smith jones 该函数将 john aaron 一分为二,并在字典中搜索 john 和 aaron单独的查询,这就是为什么我不使用外键 [以避免有很多组合 john aaron、john alan、john pierce..etc])--->有点坚持如何用键实现这个而不改变字典...也许用 CHECK?,姓氏外键是个好主意。
根据部门和当前日期从另一个表中获取 cicle(因为一个人可以在同一个部门的表中出现两次但在不同的 cicle 中)--->我怎样才能以更有效的方式获取此 cicle 值做正确的搜索?
最后,在完成所有这些验证之后,我需要确切知道未满足哪个验证(因此字段注释),因此触发器连接所有失败验证的字符串,如下所示:
lastname not in dictionary, cannot calculate pid (invalid date), name not in dictionary
我知道,如果不满足约束检查,我所能做的就是将记录插入另一个表中并显示约束失败错误消息,但这只会让我得到一个验证,对吗?但我需要验证所有这些并将报告发送给其他部门,以便他们可以查看数据并对其进行所有必要的调整。
无论如何,这是我现在的情况,我会探索可能性,希望你能分享一些关于整个过程的信息,非常感谢你的时间。