代码之家  ›  专栏  ›  技术社区  ›  Gandalf

结果设置并选择*性能

  •  5
  • Gandalf  · 技术社区  · 15 年前

    “从…中选择*” -并准备开始检查实际需要哪些列 从..中选择x,y。。 他们。但是通读 结果集 类似乎表明大多数数据都是延迟加载的。当你做一个 它会在数据库中移动光标(在本应用程序中为Oracle 10g),并在执行以下操作时移动光标: ResultSet.getXX() 它检索该列。所以我的想法是如果你 “选择*” 但是,只检索您想要的列,并不会真正影响性能。我想得对吗?我能想到的唯一一个地方是数据库内部,因为它将查询结果存储在内存中,并且需要使用更多的内存,如果只选择了几行,则需要使用更多的内存,但如果它实际上只存储指向命中查询的列的指针,则即使是这种情况也不会发生。

    思想?

    注:这仅适用于标准 结果集 ,我知道 缓存结果集

    6 回复  |  直到 15 年前
        1
  •  6
  •   skaffman    15 年前

    这一切都非常依赖于您的数据库、驱动程序和应用程序,大多数概括都是毫无意义的。

        2
  •  4
  •   Justin Cave    15 年前

    根据表结构、Oracle版本和所涉及的索引,完全有可能通过更好地更改查询计划来更改所选择的列集,从而显著提高性能。对于大多数查询,性能优势可能很小,但总的来说,显式命名列通常是一种良好的做法。

    当您有一个优化器可以使用的“覆盖索引”时,最简单的情况就是性能会得到提高。如果选择的所有列和筛选的所有列都是单个索引的一部分,则该索引是查询的覆盖索引。在这种情况下,Oracle可以避免从表中读取数据,而只读取索引。

    在其他情况下,性能也将得到改善。优化器可能能够执行以下操作: table elimination 如果有查询,则存在不会影响最终输出的临时联接。如果选择所有列,则无法进行优化。如果表中有链接行,则删除列也可以消除获取已删除列所在的其他块的需要。如果表中有LONG列和LOB列,不选择这些列也会带来很大的改进。

    最后,删除列通常会减少Oracle在通过网络传送结果之前对结果进行排序和散列所需的空间量。而且,即使结果集可能会在应用服务器的RAM中延迟加载数据,它也可能无法通过网络延迟获取列。如果从表中选择所有列,JDBC驱动程序可能必须一次至少获取一个完整的行(更可能是每次网络往返获取10或100行)。而且,由于驱动程序不知道何时获取数据以及将请求哪些列,因此您必须通过网络发送所有数据。

        3
  •  3
  •   aperkins    15 年前

    我知道,在我参与的一个应用程序中,大数据量(和大表大小)从 挑选* 选择x,y

        4
  •  3
  •   codemonkey    15 年前

    在我工作过的环境中,作为一项规则,SELECT*从未被使用过。我相信斯卡夫曼公司,;aperkins关于性能增益很小的说法可能是正确的。作为一名数据库开发人员,我有一个强烈的观点,那就是您应该始终命名要检索的列,但我想这可能没有真正的依据。

    六羟甲基三聚氰胺六甲醚。。。我想,从可维护性的角度来看,有人可能会说,命名正在检索的列有助于自我记录代码。SELECT*不会给其他开发人员提供更多的信息。无论是否,;性能上的小优势证明了额外输入的合理性,我不确定。

        5
  •  3
  •   DCookie    15 年前

    我支持@skaffman和其他人的观点——充其量只是一点小小的收获。如果您考虑Oracle如何检索数据并记住它是块I/O,那么不管您在客户机中请求哪些列,数据库都将获取记录所在的整个块。如果您的客户机总是检索整个记录(例如,在SQL*Plus中执行SELECT*操作),那么性能可能会有所提高,但在您的情况下,如果您要求传输数据,则可能不会有太多。

    对于已编译的应用程序,“选择*”可能是有害的。如果表发生更改,代码可能会中断。这就是为什么我不会用它。

    1. Justin对某些情况下可能出现的显著性能改进提出了很好的观点。
    2. Codemonkey在自我记录代码方面做得很好。
    3. Aperkins和skaffman提出了最好的建议之一:尝试一下,测量一下,看看你自己的情况会有什么影响。

    +到处都是。。。 我看不到有人对自己推荐使用“选择*”而感到失望。如果很容易指定所需的确切列,我会修改代码来实现这一点。

        6
  •  1
  •   JohnRegner    15 年前

    在切换语句时,我从来没有注意到其中一个语句与另一个语句之间有任何性能提升—我相当肯定Oracle会首先获取整行内容,而不管通配符或列规格如何。在此之前,要检查的性能因素要大得多(索引、硬盘速度等)。

    SELECT * “。指定特定列确实会使每个查询的意图更加明显。这有助于生成良好的自文档代码。写出列名也有助于我在编写查询时了解我计划对其执行的操作。