SELECT * 真的比只选择需要的列花费更多的时间吗?
Posted
技术标签:
【中文标题】SELECT * 真的比只选择需要的列花费更多的时间吗?【英文标题】:Does SELECT * really take more time than selecting only the needed columns? 【发布时间】:2014-04-18 14:31:48 【问题描述】:它会对网站页面的加载时间产生明显的影响吗?平均而言,我的表有 10 列,如果我只需要其中的 3 列,我是否应该在查询中调用这些列以使其更快?
【问题讨论】:
您从基准测试中看到了什么? 时间差异可能很小,并且可能被其他因素淹没,因此用户可能不会单独注意到(但它可能会与多个用户相加并变得至关重要)。如果您返回大量不需要的数据(例如存储在字段中的图像),则可能是主要例外。然而,调试、维护和可靠性可能是避免使用 SELECT * 的更好理由。 0.723 秒 vs 0.0717 秒的表格,我总结了三列和 131,563 行数据。那不是没有区别吗? 这是一个 10 倍的时间差异,这比我通常预期的要多得多。但正如其他人在下面指出的那样,这将取决于确切的条件。如果您从远程服务器检索并且(例如)返回了几个 TEXT 列,而您不需要这些列的值,那么时间差可能会很大。 【参考方案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 或 2 行来说可能看起来不多,但等到你有 100 或 1000 行...... 7 额外的数据列将显着影响整体传输延迟,特别是如果你最终不得不破坏结果集成更多的 TCP 数据包进行传输。如果您使用的是本地主机套接字,这可能不是这样的问题,但是将您的数据库移动到网络上的服务器、另一个数据中心等......并且影响将是显而易见的!
启用 mysql 查询缓存后,在结果集中存储不需要的数据会增加您的缓存空间需求 - 更大的查询缓存可能会影响性能。
一个巨大的打击可能是:如果您只需要作为覆盖索引一部分的列,则执行
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'
之间的最小速度差异,那么请进行一些速度测试。
【讨论】:
以上是关于SELECT * 真的比只选择需要的列花费更多的时间吗?的主要内容,如果未能解决你的问题,请参考以下文章