注:
此外,您还可以在下列步骤中将鼠标放在每个单独的图标上,从而仅加载和查看与该步骤相关的屏幕截图。可以通过单击各个屏幕截图来将其隐藏。
Oracle 数据库有多种优化从客户端进行的查询执行和数据检索的方法。ODP.NET 可实现这些性能优化,使 .NET 开发人员能构建更有效的数据库程序。
本教程描述了 ODP.NET 开发人员最常用的一些性能优化方法。
第一部分讨论语句缓存。有了语句缓存就不需要通过缓存首次执行语句时创建的服务器游标来重新分析每条已执行过的 SQL 或 PL/SQL 语句。后面再执行同一语句时可重复使用游标中已分析的信息,不必重新分析即可执行该语句,从而提高了性能。为了看到由语句缓存带来的性能提高,Oracle 建议只缓存那些被反复执行的语句。此外,SQL 或 PL/SQL 语句应使用参数,不应使用文字型数值。这样可充分利用语句缓存的优势,因为即使参数值在后面的执行中有所变更,也可以重复使用参数化语句中的分析信息。
第二部分显示如何使用 ODP.NET 中的 FetchSize 和 RowSize 属性控制每次数据库往返检索的数据量。进行多次往返来检索一组不同的数据效率很低。开发人员可利用这两个属性对从数据库服务器检索的数据量进行微调,从而减少数据库往返次数。
第三部分演示如何在 ODP.NET 和 Oracle 数据库之间传递 PL/SQL 关联数组。PL/SQL 关联数组允许 Oracle 传递大量同一类型的数据到 .NET 数组。这种方法提供了一种传递数据的灵活、简便的方式,它用单个参数将数据集中到一起并根据需要在两个层之间进行传递。
第四部分显示如何批处理 SQL、如何使用 Oracle REF 游标以及如何演示多活动结果集 (MARS)。批处理 SQL 可使开发人员在单次数据库往返中执行多个 SQL 语句。Oracle REF 游标是 Oracle 数据库特有的一种数据类型。它提供独特的结果集处理功能,允许灵活处理和调整数据。MARS 是 Oracle 一直支持的一个特性。它允许单个连接同时激活多个结果集。
注:
本演示中看到的性能提高不一定能反映在生产环境中看到的结果。有时,由于安装、硬件、数据库配置等差异,实际结果可能比演示结果更好或更差。例如,如果您使用位于同一机器上的客户端和服务器运行本演示,那么由于减少数据库往返次数而获得的性能提高将比在客户端和服务器位于两个不同机器上的生产环境下获得的性能提高更加明显。
返回主题列表
开始本教程之前,您应该:
查看连接字符串,允许 ODP.NET 应用程序连接到 Oracle 的示例 HR 模式。您需要修改
conString
字符串变量的口令和数据源值。
注:如果您正在访问远程 Oracle 数据实例,则需要以 //<主机名>/<SID> 格式指定数据源。
向下滚动到代码的 Demo 1 部分。注意,代码文件带有一些注释,用于标记在后续步骤中需要输入代码的区域。因此,您要确保在相关注释下输入相关的代码。这样做是为了确保以正确顺序输入代码,同时避免文件中出现代码混淆。
要查看语句缓存的工作方式,首先要在语句缓存大小设置为 0 的情况下执行一条语句 10000 次。
将语句缓存大小设置为 0。将下面的代码添加到 con1.ConnectionString 语句中,如以下屏幕截图所示:
"Statement Cache Size=0";
在同一文件中继续向下,执行相同的代码,但保持语句缓存为开启状态。将语句缓存大小设置为 1,然后重新执行上面的语句 10000 次。向下滚动,将下面的代码添加到 con2.ConnectionString 语句中,如以下屏幕截图所示:
"Statement Cache Size=1";
应用程序计算语句在缓存启用状态下的性能提高百分比。
如您所见,对反复执行的 SQL 或 PL/SQL 语句使用语句缓存后,性能得到显著的提高。要对所有 ODP.NET 应用程序启用语句缓存,也可以在 Windows 注册表中启用语句缓存。
不要按 Enter 键。要继续执行程序,在后面的主题中为程序添加代码。关闭命令窗口。
返回主题列表
对每次数据库往返取回的数据量进行控制可以优化应用程序的性能。例如,当最终用户需要整行数据时,如果每次往返只检索半行数据,则效率很低。与进行两次往返相比,一次往返应该能获得最佳性能。ODP.NET 允许开发人员自动发现查询行大小并指定每次往返检索的行数。该特性为 .NET 程序员极大地简化了数据检索的优化过程。
在本主题中,您将运行一个查询,一次取回一行数据,然后再运行同一查询,一次取回 100 行数据,以此查看由于减少往返次数而带来的性能提高。执行以下步骤:
首先在 OracleDataReader 上的 FetchSize 设置为 1 的情况下执行一个查询。
注:
当 ODP.NET 执行 OracleCommand 时,它首先按行大小检索元数据并填写 RowSize 属性。之后,开发人员可以用行数乘 RowSize 设置每次往返从数据库检索的数据量。在本例中,每次往返仅检索一行。
向下滚动到代码的 Demo 2 部分。定位到 for 循环。输入以下代码:
reader.FetchSize = cmd.RowSize * 1;
因为 RowSize 在运行时决定,所以查询或基础模式可以更改,但是每次往返将仍然检索相同的行数。您可以比较此步骤中 FetchSize 设置为 100 行与 FetchSize 设置为 1 行时的时间差异。
向下滚动到下一个
for
循环。输入以下代码:
reader.FetchSize = cmd.RowSize * 100;
注:
您可以在上一主题中运行的 Demo 1 部分中去掉
for
循环
的注释,以避免在已经执行过的演示上浪费时间。仅去掉循环注释不会影响剩余教程主题的结果,只会节省由于重复执行循环而浪费的时间。
如果不对 Demo 1 部分的
for 循环
进行注释,则在得到 Demo 1 部分的结果后,按 Enter 键以继续执行此部分的程序。
检查完代码之后,可以执行应用程序以查看结果。选择
Build > Build Solution
。
选择
Debug > Start Debugging
或按
F5
键。