为什么性能select * from table
不如select col_1,col_2 from table
?据我了解,占用时间的是行的定位,而不是返回多少列。
2 回答
选择不必要的列可能会导致查询计划更改,从而对性能产生巨大影响。例如,如果有一个索引,col_1, col2
但表中还有其他列,则select *
查询必须执行全表扫描,而select col_1, col_2
查询可以简单地扫描可能要小得多的索引,因此成本要低得多询问。如果您开始处理涉及多个表或涉及针对视图的查询的查询,选择列的子集有时还可以通过允许 Oracle 消除不必要的连接或函数评估来更改查询计划。现在,公平地说,查询计划会根据选择的列而改变并不是特别常见,但是当它发生时,这种改变通常是显着的。
如果您从数据库外部的应用程序发出 SQL 语句,选择其他列会强制 Oracle 通过网络发送其他数据,因此您的应用程序将花费更多时间等待网络 I/O 发送它不感兴趣的数据。这可能非常低效,特别是如果您的应用程序曾经部署在 WAN 上。
选择不必要的列还可以强制 Oracle 在不更改计划的情况下执行额外的 I/O。例如,如果表中您不需要的列之一是LOB
,Oracle 将不得不做额外的工作来获取该LOB
数据。如果数据存储在磁盘上的链接块中,但您感兴趣的列恰好位于第一行片段中,则 Oracle 不必为指定列子集的查询获取额外的行片段。select *
另一方面,执行 a 的查询必须获取每一行片段。
当然,那是在考虑维护方面之前。如果您在 PL/SQL 之外编写应用程序,则执行此SELECT *
操作意味着当将来有人向表中添加新列时您的代码将中断,或者您的应用程序必须在运行时动态确定正在运行的列集返回以自动适应新列。虽然这当然是可能的,但它可能会导致代码更复杂,因此更难以调试和维护。如果您正在编写 PL/SQL 并将数据提取到%ROWTYPE
变量中,那么SELECT *
在生产代码中执行代码是完全合理的;在其他语言中,如果您执行SELECT *
.
当您执行 SELECT * 时,存在从表的数据字典中查找定义的问题。
当您需要的唯一列是 col_1 和 col_2 时,还有一个问题是数据库做的工作比必要的多。对于大型表来说,这尤其是一个问题。
并且存在网络带宽被大于所需数据集不必要地吞噬的问题。
执行 SELECT * 不是最佳做法。它还使嵌入式 SQL 代码更难阅读。