2012-08-09 38 views
3

为什么select * from table的性能不如select col_1,col_2 from table?据我所知,这是行占用时间的位置,而不是返回多少列。oracle中select * vs select colname的性能

+0

请参阅[*此*](http://stackoverflow.com/questions/3180375/select-vs-select-column) – alfasin 2012-08-09 22:49:22

+0

您是指仅有两列的表格吗? – 2012-08-10 00:45:02

回答

9

选择不必要的列可能会导致查询计划更改对性能产生巨大影响。例如,如果col_1, col2上有一个索引,但表中还有其他列,则select *查询必须执行全表扫描,而select col_1, col_2查询可以简单地扫描可能更小的索引,因此很多查询成本较低。如果您开始处理涉及多个表的查询或涉及查询的查询,则选择列的子集有时也可以通过允许Oracle消除不必要的连接或功能评估来更改查询计划。现在,公平地说,查询计划将根据所选列进行更改并不常见,但如果这样做,更改通常很重要。

如果您从数据库外的应用程序发出SQL语句,则选择其他列会强制Oracle通过网络发送其他数据,这样您的应用程序将花费更多时间等待网络I/O发送数据不感兴趣,这可能是非常低效的,特别是如果你的应用程序被部署在WAN上。

选择不必要的列也可以强制Oracle在不更改计划的情况下执行额外的I/O。例如,如果您不需要的表格中的某一列是LOB,则Oracle必须执行额外的工作才能获取LOB数据。如果数据存储在磁盘上的链接块中,但您感兴趣的列恰好位于第一行中,则Oracle不必为指定列的子集的查询获取额外的行块。另一方面,执行select *的查询必须提取每一行。

当然,这是在考虑维护方面之前。如果您正在编写PL/SQL之外的应用程序,那么执行SELECT *意味着在将来有人向表中添加新列时代码会中断,或者您的应用程序必须在运行时动态确定一组列被返回以自动适应新列。虽然这当然是可行的,但它很可能导致代码更复杂,因此更难以调试和维护。如果您正在编写PL/SQL并将数据提取到%ROWTYPE变量中,那么在生产代码中执行SELECT *可能是完全合理的;在其他语言中,如果您执行SELECT *,则通常会设置自己的维护噩梦。

+0

+ +1为了将大局置入考虑范围......即,将数据发送到Oracle外的应用程序 – Victor 2012-08-10 16:27:57

0

当您执行SELECT *时,存在从数据字典中为表查找定义的问题。

当您需要的唯一列是col_1和col_2时,还有一个问题是数据库要做的工作多一点。对于大型表格,这尤其是个问题。

而且存在网络带宽被大于所需数据集所吞噬的问题。

这不是做SELECT *的最佳做法。 它也使嵌入式SQL代码难以阅读。

+0

在(hard?)解析时间,Oracle需要在数据字典中查找“select *”还是“select col_1,col2”。不查看数据字典,Oracle不会知道col_1和col_2是否是表,函数等中的列。也不知道行的哪里查找它们,数据类型等。 – 2012-08-09 23:32:38