Delphi 甲骨文-阿伦';t存储过程优先于应用程序内查询?

Delphi 甲骨文-阿伦';t存储过程优先于应用程序内查询?,delphi,stored-procedures,oracle10g,delphi-2010,Delphi,Stored Procedures,Oracle10g,Delphi 2010,我一直听说并相信存储过程是SQL数据库的核心,它们是用于多种用途的最佳对象。许多人甚至使用存储过程而不是触发器。在我的Delphi应用程序中,我查询一个包含20.000多行的表,每行由大约20列组成。当我对存储过程执行此操作时,加载大约需要3秒钟,但如果使用查询,则不到1秒钟。这一点非常重要,因为该表将容纳超过一百万条记录。我需要选择最佳的方式,因为我确信,当表中充满那么多记录时,它永远不会少于10秒。为什么存储过程要比临时查询花费更长的时间。存储过程通常是首选的,因为它们促进了更好的代码组织,

我一直听说并相信存储过程是SQL数据库的核心,它们是用于多种用途的最佳对象。许多人甚至使用存储过程而不是触发器。在我的Delphi应用程序中,我查询一个包含20.000多行的表,每行由大约20列组成。当我对存储过程执行此操作时,加载大约需要3秒钟,但如果使用查询,则不到1秒钟。这一点非常重要,因为该表将容纳超过一百万条记录。我需要选择最佳的方式,因为我确信,当表中充满那么多记录时,它永远不会少于10秒。为什么存储过程要比临时查询花费更长的时间。

存储过程通常是首选的,因为它们促进了更好的代码组织,并且使DBA和数据库开发人员更容易优化代码。但是,如果存储过程只是打开并返回一个
SYS\u REFCURSOR
,那么与发出相同SQL语句的应用程序相比,性能应该没有差别

  • 您的查询只是打开一个
    SYS\u REFCURSOR
    并返回它吗?还是它在做别的事情
  • 这两个查询都使用绑定变量吗?还是用文字来代替
  • 两种方法的查询计划是否相同
  • 在这两种情况下获取的行数是否相同?或者,在发出direct SQL语句时可能只是获取前N行,而在使用存储过程时则获取所有行

您必须始终预先考虑使用存储过程来完成繁重的工作,因为有许多建议,如在服务器端运行和使用服务器资源(快速硬盘、CPU和内存),可以减少网络流量的使用。例如,如果您需要对一大组记录进行复杂的计算,您可以编写一个存储过程来解决该任务,而不是检索数据集并在应用程序中自行处理

注意:当您说
…在我的Delphi应用程序中,我查询一个包含20.000多行的表时
,我真的希望您不要将+20.000记录带到您的应用程序中,因为这不是有效的方法(相反,您必须过滤您的记录,添加带有适当条件的Where子句,或者您可以使用分页方法)

现在关于你的特别问题,我有一些想法

  • ORACLE有一个工具,可以对查询进行哈希处理和存储,以改进执行。可能您的查询正在使用此功能
  • 另一种选择是,您的查询速度比存储过程快,因为您可能正在使用一个仅向前的数据集组件,该组件一次只检索一小部分记录

为了给您提供备选方案,您必须提供更多信息,如您正在使用的SQL组件、示例SQL语句,并指出您是否正在检索所有记录以供应用。

我使用Oracle已经超过8年了,以下内容对于管理性能非常有效,我有几个表的行数超过了一百万行:

  • 对涉及数据操作的逻辑使用存储过程
  • 查看数据时使用Select语句,无需存储过程。我有更好的事情要做,而不是在我的应用程序中创建另一个没有任何好处的层
  • 在SQL语句中使用绑定变量,Oracle会缓存所有语句,但如果使用绑定变量,效率会更高
  • 查看查询的顺序,确保有正确的索引,以避免对大型表进行全表扫描,因为它们会降低性能。请注意,表上的索引过多也会降低更新和插入性能
  • 使用Oracle的索引可以调用函数,例如,我们通常不关心日期字段中的时间,因此我们的索引是
    create index idxname on tablename(trunc(datefield))
  • <> LI>当构建具有大表的强应用程序>强>绝对值>时,请考虑将所有行返回给应用程序。构建一个屏幕,允许用户在数据中搜索所需的记录。仅网络IO就使得返回所有行的设计不是一个好主意
  • oracle网站上有几篇关于性能和性能的文章

我使用Devart的UniDac组件套件与Oracle合作。实际上,我的表中大约有190000条记录,我只是查询了其中的20000条。我的SQL语句是“从退休人员中选择*,其中DEPARTID=118”。我在选择列表中不使用星号(*),而是提供所有列名,因为我知道使用星号会影响性能。您的最后一点帮助我找到了问题。是的,在使用UniQuery组件时,我实际上并没有一次获取所有行,但在使用UniStoredProc时,我一次获取所有行。默认的FetchRows属性是25,我在查询组件中没有更改它。现在,在调整这个参数之后,我用存储过程得到了更快的结果。谢谢大家,如果重用的话,muchOracle将缓存任何语句以避免硬解析。用许多不同的查询充斥数据库,这些查询只在应该是“绑定变量”的内容上有所不同,这是一种使缓存效率低下的好方法。可以使用不同的游标共享值作为解决方法,但SP或bind变量是更好的选择。SP甚至可以为选择提供好处(即更好的安全性…),但这些好处应根据需要进行权衡。全表扫描并不总是坏事,索引也不总是好事。请参阅Tom Kyte博客(或书籍)以获得完整的解释。注意触发器。。。它们降低了应用程序的可维护性。如果需要在一次调用中更新多个表/行,则存储过程要好得多。