VSAM 搜索与 COBOL search/loop
VSAM Search VS COBOL search/loop
我有一个可能包含大约 300 万条记录的文件。该文件的某些记录将需要在整个程序的 运行 期间多次更新。如果我需要从这个文件中提取特定的记录,下面哪个更有效:
- 索引 VSAM 搜索
- 包含 COBOL 搜索的索引平面文件
- 将所有数据缓冲到工作存储中并编写循环来处理搜索
显然,如果您可以将所有数据缓冲到内存中(并且如果主机系统可以支持工作集足够大的页面 实际上 保留在 RAM 中而不需要分页,那么这可能是最快的方法。
但是,要非常小心地考虑由虚拟内存分页子系统引起的 "hidden disk-I/O"!如果请求的 "in-memory" 数据实际上是 而不是 "in memory," 将发生页面错误并且您的进程将停止在其轨道上直到页面被检索. (如果 "page stealing" 发生,那么,你就有麻烦了。你的 "in-memory" 策略刚刚变成了一个可能非常低效(!)的基于磁盘的策略。如果密钥是随机分布的,那么你的过程有一个巨大的工作集,它正在 随机访问。 如果该内存的 all 实际上不是 在记忆中,并会留在那里,你有麻烦了。
如果您正在更新一个大文件,请考虑在处理它之前排序 updates-delta 文件,以便所有出现的相同键都相邻。您现在可以编写您的 COBOL 程序来利用此 (当然,如果检测到乱序记录,则 abend
!)。 如果"this" 记录中的密钥与 "previous" 记录中的密钥相同,则无需重新读取记录。 (而且,您实际上不需要 write 旧记录,直到键确实发生变化。)由于索引文件访问方法是通过键的连续性呈现的,因此每个键都可能成为 "close to" 之前请求的那个,这样一些必要的索引树页面就已经在内存中了。显然,您需要对此进行基准测试,但排序文件所花费的时间可能远少于索引查找所花费的时间。 (这实际上是相当可观的。)
Mike 的回答中有关于 "hidden I/O" 的重要问题(取决于机器、配置、数据量)...
如果您很可能需要更新许多记录,Mike 建议的选项是最有用的选项。
如果您很可能不需要更新太多记录(我猜您可能低于 2%),另一种方法可能会更快(需要基准测试!):
- 通过索引 VSAM 搜索读取每个键
- 将更改的记录存储在内存中(发生大table),如果您只更改一些值并且记录很大,则只存储所有可能的更改值+键在table没有实际的
REWRITE
- 在进行 VSAM 搜索之前:如果您阅读了密钥,请查看您的出现 table
已经从那里获取值或获取新值
- ...
- 在程序结束时:检查你的发生和
REQRITE
所有记录(如果你有完整的记录REWRITE
就足够了,否则你需要先READ
获取完整记录)
性能常为:"know your data and possible program flow, then try the best 2-3 approach, benchmark and decide".
我有一个可能包含大约 300 万条记录的文件。该文件的某些记录将需要在整个程序的 运行 期间多次更新。如果我需要从这个文件中提取特定的记录,下面哪个更有效:
- 索引 VSAM 搜索
- 包含 COBOL 搜索的索引平面文件
- 将所有数据缓冲到工作存储中并编写循环来处理搜索
显然,如果您可以将所有数据缓冲到内存中(并且如果主机系统可以支持工作集足够大的页面 实际上 保留在 RAM 中而不需要分页,那么这可能是最快的方法。
但是,要非常小心地考虑由虚拟内存分页子系统引起的 "hidden disk-I/O"!如果请求的 "in-memory" 数据实际上是 而不是 "in memory," 将发生页面错误并且您的进程将停止在其轨道上直到页面被检索. (如果 "page stealing" 发生,那么,你就有麻烦了。你的 "in-memory" 策略刚刚变成了一个可能非常低效(!)的基于磁盘的策略。如果密钥是随机分布的,那么你的过程有一个巨大的工作集,它正在 随机访问。 如果该内存的 all 实际上不是 在记忆中,并会留在那里,你有麻烦了。
如果您正在更新一个大文件,请考虑在处理它之前排序 updates-delta 文件,以便所有出现的相同键都相邻。您现在可以编写您的 COBOL 程序来利用此 (当然,如果检测到乱序记录,则 abend
!)。 如果"this" 记录中的密钥与 "previous" 记录中的密钥相同,则无需重新读取记录。 (而且,您实际上不需要 write 旧记录,直到键确实发生变化。)由于索引文件访问方法是通过键的连续性呈现的,因此每个键都可能成为 "close to" 之前请求的那个,这样一些必要的索引树页面就已经在内存中了。显然,您需要对此进行基准测试,但排序文件所花费的时间可能远少于索引查找所花费的时间。 (这实际上是相当可观的。)
Mike 的回答中有关于 "hidden I/O" 的重要问题(取决于机器、配置、数据量)...
如果您很可能需要更新许多记录,Mike 建议的选项是最有用的选项。
如果您很可能不需要更新太多记录(我猜您可能低于 2%),另一种方法可能会更快(需要基准测试!):
- 通过索引 VSAM 搜索读取每个键
- 将更改的记录存储在内存中(发生大table),如果您只更改一些值并且记录很大,则只存储所有可能的更改值+键在table没有实际的
REWRITE
- 在进行 VSAM 搜索之前:如果您阅读了密钥,请查看您的出现 table 已经从那里获取值或获取新值
- ...
- 在程序结束时:检查你的发生和
REQRITE
所有记录(如果你有完整的记录REWRITE
就足够了,否则你需要先READ
获取完整记录)
性能常为:"know your data and possible program flow, then try the best 2-3 approach, benchmark and decide".