首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >select *与select列

select *与select列
EN

Stack Overflow用户
提问于 2010-07-05 22:45:16
回答 12查看 90K关注 0票数 132

如果我只需要2/3列,并且我查询SELECT *而不是在select查询中提供这些列,那么在增加/减少I/O或内存方面是否会有性能下降?

如果我在不需要的情况下选择*,可能会出现网络开销。

但在select操作中,数据库引擎是始终从磁盘提取原子元组,还是仅提取select操作中请求的那些列?

如果它总是拉取一个元组,那么I/O开销是相同的。

同时,如果它拉出一个元组,那么从元组中剥离请求列可能会消耗内存。

因此,如果是这种情况,select someColumn将比select *有更多的内存开销。

EN

回答 12

Stack Overflow用户

回答已采纳

发布于 2010-07-05 22:50:26

它总是拉出一个元组(除非表已经被垂直分段-分解成列的片段),所以,从性能的角度回答您提出的问题,这并不重要。但是,出于许多其他原因(如下所示),您应该始终按名称特别选择所需的列。

它总是提取一个元组,因为(在我熟悉的每个RDBMS供应商中),所有东西(包括表数据)的底层磁盘存储结构都是基于定义的I/O页(在SQL Server中,例如,每个页是8KB)。并且每个I/O读取或写入都是按页进行的。也就是说,每次写入或读取都是一个完整的数据页。

由于这种潜在的结构约束,结果是数据库中的每一行数据必须始终位于且仅位于一页上。它不能跨越多个数据页面(除了像blob这样的特殊东西,在这种情况下,实际的blob数据存储在单独的Page-chunks中,而实际的表行列只获得一个指针...)。但这些例外只是例外,通常不适用于特殊情况(对于特殊类型的数据或特殊情况下的某些优化)。

即使在这些特殊情况下,通常情况下,实际的表行数据本身(其中包含指向Blob的实际数据的指针,或其他任何内容)也必须存储在单个IO Page上……

异常。唯一可以使用Select *的地方是在ExistsNot Exists谓词子句之后的子查询中,如下所示:

代码语言:javascript
复制
   Select colA, colB
   From table1 t1
   Where Exists (Select * From Table2
                 Where column = t1.colA)

编辑:针对@Mike Sherer的评论,是的,这是真的,无论是在技术上,还是在美学上,都为你的特殊情况下了一点定义。首先,即使请求的列集是存储在某些索引中的列的子集,查询处理器也必须提取存储在该索引中的每一列,而不仅仅是请求的列,这也是出于同样的原因-所有I/O都必须在页中完成,并且索引数据像表数据一样存储在IO页中。因此,如果您将索引页的"tuple“定义为存储在索引中的一组列,则该语句仍然为真。

这句话在美学上是正确的,因为重点是它基于存储在I/O页中的内容来获取数据,而不是根据您请求的内容,并且无论您是在访问基表I/O页还是索引I/O页,这一点都是正确的。

有关不使用Select *的其他原因,请参阅Why is SELECT * considered harmful?

票数 32
EN

Stack Overflow用户

发布于 2010-07-05 22:52:32

您永远不应该(永远不)在生产代码中使用SELECT *有几个原因:

  • 由于您没有给数据库任何关于您想要什么的提示,因此它首先需要检查表的定义,以便确定该表上的列。这种查找将花费一些时间-在单个查询中不是很多-但是随着时间的推移,它会累积起来
  • 如果你只需要2/3的列,你选择了1/3太多的数据需要从磁盘检索并通过网络发送
  • 如果你开始依赖数据的某些方面,例如列返回的顺序,一旦表被重组并添加(或删除现有列)
  • 在SQL Server中(对其他数据库不确定),你可能会得到一个令人讨厌的惊喜,总有可能非聚集索引正在覆盖该请求(包含所需的所有列)。有了SELECT *,你从一开始就放弃了这种可能性。在这种情况下,将从索引页检索数据(如果索引页包含所有必需的列),因此与执行SELECT *....查询相比,磁盘I/O 内存开销要小得多。

是的,一开始需要更多的输入(像SQL Prompt for SQL Server这样的工具甚至可以在这方面帮助你)--但这确实是一个没有例外的规则:永远不要在你的生产代码中使用SELECT *。永远不会。

票数 116
EN

Stack Overflow用户

发布于 2010-07-05 22:48:28

您应该始终只对实际需要的列执行select操作。选择less而不是more的效率永远不会降低,而且您还会遇到更少的意外副作用-比如逐个索引地访问客户端的结果列,然后通过向表中添加新列来使这些索引变得不正确。

编辑:表示访问。愚蠢的大脑还在醒着。

票数 21
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3180375

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档