【问题标题】:Does SELECT * really take more time than selecting only the needed columns?SELECT * 真的比只选择需要的列花费更多的时间吗?
【发布时间】:2014-04-18 14:31:48
【问题描述】:

它会对网站页面的加载时间产生明显的影响吗?平均而言,我的表有 10 列,如果我只需要其中的 3 列,我是否应该在查询中调用这些列以使其更快?

【问题讨论】:

  • 您从基准测试中看到了什么?
  • 时间差异可能很小,并且可能被其他因素淹没,因此用户可能不会单独注意到(但它可能会与多个用户相加并变得至关重要)。如果您返回大量不需要的数据(例如存储在字段中的图像),则可能是主要例外。然而,调试、维护和可靠性可能是避免使用 SELECT * 的更好理由。
  • 0.723 秒 vs 0.0717 秒的表格,我总结了三列和 131,563 行数据。那不是没有区别吗?
  • 这是一个 10 倍的时间差异,这比我通常预期的要多得多。但正如其他人在下面指出的那样,这将取决于确切的条件。如果您从远程服务器检索并且(例如)返回了几个 TEXT 列,而您不需要这些列的值,那么时间差可能会很大。

标签: mysql sql performance select


【解决方案1】:

它会产生可识别的不同吗?在大多数情况下可能不会。以下是一些可能会产生重大影响的情况:

  • 7 个不需要的列非常非常大。
  • 您要返回很多很多行。
  • 您有一张大表,有很多行,并且 3 列上的索引可用,但 10 列上没有。

但是,还有其他不使用*的原因:

  • 它将根据编译查询时数据库中列的顺序替换列。如果表的结构发生变化,这可能会导致问题。
  • 如果列名更改或被删除,您的查询将正常工作,后续代码可能会中断。如果您明确列出列,则查询将中断,从而更容易发现问题。
  • 键入三个列名应该没什么大不了的。明确列出列可以使代码提供更多信息。

【讨论】:

  • 关于订购和意外密码破解的要点。如果您正在访问非关联数组中的数据(例如 PHP 中的 $row[0]),这也是一个问题——代码可能不会中断,但您可能会得到意想不到的结果。想象一下表 {name, credit_card_number, email} 正在被查询以显示用户的电子邮件地址,并且有人在name 之后添加了一个列,现在echo $row[2] 显示了信用卡号
【解决方案2】:

假设您有一个包含 1000 列的表,而您只需要 3 个。

你认为什么会跑得更快,为什么?

这个:SELECT * FROM table_name;

或者这个:SELECT col1, col2, col3, FROM table_name;

当您使用* 时,您现在将整个选择(大或小)保存在内存中。选择越大......它将使用/需要的内存越多。

因此,即使您的表不一定很大,我仍然只会选择您实际需要的数据。您甚至可能没有注意到速度上的差异,但它肯定会更快。

【讨论】:

    【解决方案3】:

    是的,如果您只需要几列,请只选择那些。以下是一些原因:

    1. 最明显的: 需要将额外的数据发回,以便传输更大的数据包(或通过本地套接字进行管道传输)。这将增加整体延迟。这对于 1 或 2 行来说可能看起来不多,但等到你有 100 或 1000 行...... 7 额外的数据列将显着影响整体传输延迟,特别是如果你最终不得不破坏结果集成更多的 TCP 数据包进行传输。如果您使用的是本地主机套接字,这可能不是这样的问题,但是将您的数据库移动到网络上的服务器、另一个数据中心等......并且影响将是显而易见的!
    2. 启用 MySQL 查询缓存后,在结果集中存储不需要的数据会增加您的缓存空间需求 - 更大的查询缓存可能会影响性能。
    3. 一个巨大的打击可能是:如果您只需要作为覆盖索引一部分的列,则执行select * 将需要对主表中的剩余数据字段进行后续点查找,而不仅仅是使用索引表中的数据。

    【讨论】:

      【解决方案4】:

      是的,你应该这样做。

      在 select 中使用命名列是使用数据库的最佳实践,原因有很多。

      只有需要的数据从数据库传输到应用服务器,从而减少 CPU、内存和磁盘的使用。

      它有助于检测编码错误和结构变化。

      只有少数情况下使用 select * 是个好主意,在所有其他查询中帮自己一个忙并使用列名。

      【讨论】:

        【解决方案5】:

        是的,当然。 * 将被所有列名替换。之后只有执行开始。例如,如果一个表中有 3 列 a、b、c.. select a、b、c 直接开始执行,而 select * 开始将查询转换为 select a、b、c 之后只有执行统计信息。

        【讨论】:

          【解决方案6】:

          简而言之,是的,如果您要返回更多数据,则需要更长的时间。这可能是一个非常非常非常小的时间,但是是的,它需要更长的时间。如上所述,在您可能不是设计/实现数据库的人的生产情况下,select * 可能很危险。如果您假设列按特定顺序返回或数据库结构属于特定类型,然后 DBA 进入并进行某种更改并且没有通知您,则您的代码可能有问题。

          【讨论】:

            【解决方案7】:

            差异很小,但有细微的差异,我认为这取决于几个因素,哪个更快。

            1) 表中有多少列?

            2)您实际需要抓取多少列?

            3)你抓取了多少条记录?

            在你的情况下,根据你所说的有 10 列并且只需要其中 3 列,我怀疑如果你使用 'Select *' 会有所不同,除非你可能会抓住成千上万的记录。但在涉及更多列的更极端的情况下,我发现'Select *' 会稍微快一些,但这可能并非在所有情况下都是如此。

            我曾经在一个包含 150 多列的 SQLite 表中进行了一些速度测试,我只需要抓取大约 40 列,并且需要全部 20,000 多条记录。速度差异非常小(我们说的是 20 到 40 毫秒的差异),但实际上使用 'SELECT ALL *' 从所有列中获取数据比使用 'Select All Field1, Field2, etc' 更快。

            我假设你的表中的记录和列越多,这个例子的速度差异就越大。但是,如果您只需要一张大表中的 3 列,我猜只抓取这 3 列会更快。

            不过,如果您真的关心 'Select *''Select field1, field2, etc' 之间的最小速度差异,那么请进行一些速度测试。

            【讨论】:

              猜你喜欢
              • 2014-02-26
              • 2022-09-30
              • 2015-11-02
              • 2015-09-13
              • 2019-11-22
              • 2012-02-18
              • 2016-05-22
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多