当使用JDBC,我经常遇到结构喜欢

ResultSet rs = ps.executeQuery();
while (rs.next()) {
    int id = rs.getInt(1);
    // Some other actions
}

我问我自己(和提交人的代码)为什么不使用检索标签列价值观:

int id = rs.getInt("CUSTOMER_ID");

最好的解释我听说的东西有关的性能。但实际上,它使处理速度极快?我不这么认为,虽然我从来没有进行测量。甚至如果通过检索标签将是一个比较慢,尽管如此,它提供更好的可读性和灵活性,在我的意见。
所以可能有人给我很好的解释的避免检索列值列索引,而不是列标签吗?什么优点和缺点的办法(或许,关于某些DBMS)?

有帮助吗?

解决方案

你应该使用 串片公司的财产的默认。

赞成:

  • 独立的列顺序
  • 更好的可读性/可维修性

缺点:

  • 你有没有控制的列名称(通过存储程序)

你会喜欢吗?

int?

int i=1;
客户id=结果集。getInt(i++);
自定义名称=结果集。形式(i++);
址=结果集。形式(i++);

或串?

客户id=结果集。getInt("customer_id");
自定义名称=结果集。形式("customer_name");
址=结果集。形式("customer_address");

如果有什么是新的列中插入的位置1?哪个代码,你会喜欢吗?或者,如果列的顺序被改变了,这代码版本,你会需要改变呢?

这就是为什么你应该使用 串片公司的财产的默认。

其他提示

警告:我会在这里夸夸其谈,因为这让我发疯了。

99%*的时间,这是一个荒谬的微观优化,人们有一些模糊的想法让事情“变得更好”。这完全忽略了这样一个事实:除非你一直处于数百万个SQL结果的非常紧张和繁忙的循环,这很有可能是罕见的,你永远不会注意到它。对于那些没有这样做的人来说,维护,更新和修复列索引中的错误的开发人员时间成本远远大于无限可执行应用程序的硬件增量成本。

不要对这样的优化进行编码。维护它的人的代码。然后观察,测量,分析和优化。再次观察,再次测量,再次分析,再次优化。

优化几乎是开发的最后一步,而不是第一步。

*图组成。

答案已被接受,尽管如此,这里还有一些我尚未看到的其他信息和个人经验。

通常使用列名(常量而不是文字),如果可能的话。这样更清晰,更易于维护,未来的更改不太可能破坏代码。

但是,列索引有一个用途。在某些情况下,这些更快,但不够充分,这应该覆盖名称*的上述原因。在开发处理 ResultSet 的工具和常规方法时,这些非常有用。最后,可能需要索引,因为该列没有名称(例如未命名的聚合)或者有重复的名称,因此没有简单的方法来引用它们。

*请注意,我已经编写了一些JDBC驱动程序并查看了一些开放源代码,并在内部使用列索引来引用结果列。在我使用的所有情况下,内部驱动程序首先将列名映射到索引。因此,您可以轻松地看到列名称在所有这些情况下总是需要更长时间。但对于所有司机来说可能并非如此。

来自java文档:

  

ResultSet接口提供了getter方法(getBoolean,getLong等),用于从当前行检索列值。可以使用列的索引号或列的名称来检索值。通常,使用列索引会更有效。列从1开始编号。为了获得最大的可移植性,每行中的结果集列应按从左到右的顺序读取,每列应只读一次。

当然,每个方法(命名或索引)都有它的位置。我同意命名列应该是默认值。但是,在需要大量循环的情况下,以及在代码(或类)的同一部分中定义和维护SELECT语句的情况下,索引应该没问题 - 建议列出所选的列,而不仅仅是“SELECT * FROM ...”,因为任何表更改都会破坏代码。

当然,使用列名可提高可读性并简化维护。但使用列名称有另一面。如您所知,SQL允许多个具有相同名称的列名称,不能保证您在resultSet的getter方法中键入的列名实际上指向您要访问的列名称。理论上,使用索引号而不是列名是优先的,但它会降低可读性......

由于

我认为使用标签不会影响性能。但是还有另一个原因是不使用 String 。或者 int ,就此而言。

考虑使用常量。使用 int 常量可使代码更易读,但也不太可能出错。

除了更具可读性之外,常量还可以防止您在标签名称中输入拼写错误 - 如果您这样做,编译器将抛出错误。任何有价值的IDE都会捡起它。如果您使用 String s或 ints ,则情况并非如此。

我在Oracle数据库上对这个确切的主题进行了一些性能分析。在我们的代码中,我们有一个包含大量列和大量行的ResultSet。在请求执行方法的20秒(!)中,oracle.jdbc.driver.ScrollableResultSet.findColumn(String name)大约需要4秒。

显然整体设计有问题,但使用索引代替列名可能需要4秒钟。

你可以充分利用两者!使用索引的速度与使用列名的可维护性和安全性。

首先 - 除非你通过结果集循环,否则只使用列名。

  1. 定义一组整数变量,每个变量对应一个您要访问的列。变量的名称可以包括列的名称:例如iLast_Name。

  2. 在结果集循环之前,通过列元数据进行迭代,并将每个整数变量的值设置为相应列名的列索引。如果'Last_Name'列的索引为3,则将'iLast_Name'的值设置为3.

  3. 在结果集循环中,使用GET / SET方法中的整数变量名称。对于正在访问的实际列名,变量名是开发人员/维护者的直观线索,但值是列索引,将提供最佳性能。

  4. 注意:初始映射(即列名到索引映射)仅在循环之前完成一次,而不是循环中的每个记录和列。

JDBC驱动程序负责索引查找的列。因此,如果每次驱动程序进行查找(通常在哈希映射中)时都按列名提取值,则检查列名称的相应索引。

我同意先前的答案,性能是没有东西可以迫使我们选择的办法。它将是很好的考虑以下事情:

  • 代码可读性:对于每一个开发的阅读你的代码标签,有更多的意义比索引。
  • 维护:想SQL query和它的方式保持。什么是更有可能发生在你的情况之后修/改善/重构SQL query:改变列的顺序提取的或改变导致列名。它似乎对我来说改变的顺序列提取的(如果结果的增加或删除新列结果集)具有更大的概率发生。
  • 封装:尽管你选择的方式尝试找出代码在哪里你跑SQL查询和分析结果设置在同一个部件,并使只有这个成分意识到有关列名和他们的映射的索引(如果你决定用他们)。

使用索引是一种优化尝试。

开发人员需要额外的努力来查看必要的数据,以检查他们的代码在更改后是否能正常工作,从而节省了时间。

我认为这是我们使用数字而不是文本的内在本能。

除了在Map中查找标签外,它还会导致额外的String创建。虽然它会在堆栈上发生,但它仍然会带来成本。

这一切都取决于个人选择,直到日期我只使用了索引: - )

正如其他海报所指出的那样,我会坚持使用专栏名称,除非你有一个非常有力的理由不这样做。与例如查询优化相比,对性能的影响可以忽略不计。在这种情况下,维护比小型优化更重要。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top