【问题标题】:Query optimization in Delphi 4Delphi 4 中的查询优化
【发布时间】:2011-12-15 06:35:11
【问题描述】:

在 Delphi 4 中,我们有一个 SELECT 查询,它使用 TQuery 组件一次获取 3 个文本类型字段以及其他必填字段。
有超过 1,000 条记录(将来可能会增加)。
此查询消耗大量内存。我认为由于下一个查询需要大量时间来执行。

我正在使用 BDE 连接到 SQL 服务器。

我需要优化性能,这样就不会花费太多时间。请指教。

【问题讨论】:

  • 我很确定 ADO 直到 Delphi 5 才引入(甚至可能更晚)。
  • TQuery 绝对不是最好的方法!一方面,它是为史前的 Borland 数据库引擎设计的
  • TQuery 使用 BDE,它已经过时了很长时间。您最好先升级并使用现代数据访问组件(AnyDAC、UniDAC 或 dbExpress)
  • 就能够回答您的问题而言,需要更多详细信息:1)您使用的是什么数据库引擎?如果是 Paradox/DBase ……你就犯了一个悲惨的错误! 2)查询在做什么?它只是一个 SELECT,还是一个多条件更新?请提供更多信息!
  • 1) TQuery 使用 BDE,2) 它只是一个 SELECT 查询。

标签: sql-server delphi query-optimization tquery delphi-4


【解决方案1】:

您应该考虑某种分页机制。不要向客户端获取 1000 条(或 100 万条)记录,而是使用带有 SQL-server ROW_NUMBER() 的分页来获取每页 50-100 条记录的块。

这样的查询:

SELECT id, username FROM mytable ORDER BY id

可能看起来像这样:

SELECT * FROM (
SELECT id, username, TOTAL_ROWS=Count(*) OVER(), ROW_NUMBER() OVER(ORDER BY id) AS ROW_NUM
FROM mytable 
) T1
WHERE ROW_NUM BETWEEN 1 AND 50

应将ORDER BY 字段编入索引(如果可能)以加快处理速度。

【讨论】:

  • 好主意,但据我所知,该应用程序使用的是BDESQL Links,它们不支持ROW_NUMBER()。我认为它当时不存在于SQL ServerBDE 已被弃用十多年了。
【解决方案2】:

如果您使用TQuery,请确保在检索循环之外使用本地TField 以加快处理速度(FieldByName 方法有点慢)。

您可以尝试我们的免费软件开源类来访问任何数据库引擎。

它通过 OleDB 提供对 MS SQL 的直接访问,无需调用 ADO 层。

它针对速度进行了非常优化,并且支持 Unicode,即使在旧版本的 Delphi 上也是如此。它已经在 Windows XP、Vista 和 7(包括 64 位)上进行了测试。

它有一个TQuery 模拟器:这不是DB.pas 单元中定义的真正的TQuery,而是一个具有大多数相同方法的类。而且您不需要使用所有 BDE 类和单元。缺点是您不能使用 Delphi DB 可视化控件,但对于快速 TQuery,它可以完成工作。

它有一些独特的功能(例如用于字段访问的后期绑定),值得考虑。

它不需要任何第三方库(如 BDE),并且适用于从 Delphi 5 到 XE2。我猜它也会在 Delphi 4 下运行。

您可以下载并寻求支持in our site

【讨论】:

    【解决方案3】:

    真正获取TEXT 列值需要时间和内存。

    为了加快获取速度,请从 SELECT 列表中排除 TEXT 列。并且仅在您真正需要它们的值时使用记录主键的附加查询来获取它们。

    要减少内存使用量,请使用Unidirectional 或以上查询。

    【讨论】:

      【解决方案4】:

      为了减少时间(取决于数据),我们可以在查询中使用 DATALENGTH。

      喜欢

      DATALENGTH(TEXT) <> 0
      

      这不会加载在TEXT 字段中没有值的记录。

      【讨论】:

        【解决方案5】:
        • 您定义了哪些字段类型?如果它们很大,它们会占用内存,对此您无能为力。你可以尝试不同的库,有些足够聪明,只分配字段的实际大小而不是声明的,其他的总是分配声明的,所以如果你有 4000 个字符和 1000 条记录的三个字段,你将有 3 *仅为文本字段分配 4000 * 1000 字节。
        • 您需要一次加载整个数据集吗?使用 where 条件和/或增量获取仅获取所需的数据将有助于减少内存并可能减少执行时间
        • 如果查询需要很长时间才能执行,您必须了解原因和位置。它可能是查询执行时间本身,也可能是将结果集传输到客户端应用程序所花费的时间。您需要分析您的查询以了解实际的问题,并采取适当的纠正措施。 1000 条记录在今天是一个非常小的数据集,如果它很慢,那就是真的很糟糕。
        • 每个数据库都有细微的优化差异。您必须仔细研究您正在使用的数据库,并为该数据库编写正确的查询 - 在您设计正确的数据库之后。

        只是更改数据库组件而不确定确切的原因显然是愚蠢的,如果问题出在其他地方只是浪费时间。 BDE 运行良好,尤其是与 ADO 相比。而且微软也在取消对 ADO 的支持,因此我不会在它上面投入时间和金钱。

        更新:知道为什么这个答案被否决会很有趣。就因为ADO信徒以后日子不好过,觉得有必要隐瞒真相?

        继续反对白痴。你只是表现出你的无知!

        【讨论】:

        • "Microsoft 正在取消对 ADO 的支持" 这对我来说真的很有趣。你有任何链接或类似的东西可以证实你在这里所说的话吗?这个链接有点不同意你。 msdn.microsoft.com/en-us/library/ms810810.aspx
        • 感谢您提供链接,但博文中未提及 ADO。 SQL Server OLE DB 提供程序与 ADO 不同。将 ADO 与 SQL Server Native Client 提供程序一起使用显然非常好。
        • @Mikael:ADO 是 OLEDB 的“无指针”包装器。如果您查看 URL 中的体系结构图,您会发现 ADO 构建在 OLEDB 之上。它还说“在 SQL Server 2012 之后,SQL Server Native Client OLE DB 提供程序将不再包含在 SQL Server Native Client 中。”和“新应用程序应使用 SQL Server Native Client ODBC 驱动程序”。 Microsoft IS 不再支持 ADO 并返回 ODBC。
        • @MadHatter - ADO(至少我相信)基本上是记录集对象。 msdn.microsoft.com/en-us/library/windows/desktop/… 这可以在没有 SQL Server OLEDB 提供程序的情况下存在。例如,您可以使用 MSDASQL.1,它是 ODBC 驱动程序的 OLEDB 提供程序。所以……在我对 ADO 即将消失的事实采取行动之前,我需要更多的东西。我同意它是旧的或者不是最新的。例如,您将在使用带有 ADO 的 SQL Server Native Client 和带有 XML 数据类型的列时遇到麻烦。 MDAC 驱动程序通过将 XML 视为 ntext 来处理它。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-10-16
        • 1970-01-01
        • 1970-01-01
        • 2017-06-08
        • 2011-09-14
        • 1970-01-01
        • 2015-09-25
        相关资源
        最近更新 更多