SQL通配符:性能开销?

3
我已经在谷歌上搜索了这个问题,但似乎找不到一致的意见,或者很少有基于可靠数据的意见。我只想知道,在 SQL SELECT 语句中使用通配符是否比逐个调用每个项产生额外的开销。我已经在多个不同的测试查询中比较了两者的执行计划,似乎估计总是相同的。是否可能会在其他地方产生一些开销,还是它们真正地被相同处理?
具体指的是:
SELECT *

对比。

SELECT item1, item2, etc.

你能举个小例子来说明吗? - Pablo Santa Cruz
3
请注意,在生产代码中使用通配符符号通常是糟糕设计的一个征兆,你不应该这样做,永远不应该。永远、永远地不应该。我记不住足够多的“永远”了。 - Mark Canlas
我同意,并且出于这个确切的原因,我从不使用*。然而,我曾经读到一些模糊的观点,认为在SELECT语句中使用通配符会产生一些开销,只是想要一些基于事实的澄清,但我很难找到。 - Geo Ego
5个回答

9
SELECT * FROM...

并且

SELECT every, column, list, ... FROM...

两者执行的结果相同,因为都是未优化的扫描。

不同之处在于:

  • 额外查找sys.columns以解析*
  • 当表模式更改时,合同/签名会发生变化
  • 无法创建覆盖索引。实际上,没有任何调整选项
  • 如果非schemabound,则需要刷新所需的视图
  • 无法使用*索引或schemabind视图
  • ...和其他东西

关于同一主题的其他SO问题...


另外,我认为与从磁盘中获取数据所需的实际工作相比,通配符解析中的“开销”可以忽略不计。 - Mark Canlas
没错,但人们经常提到它。当然,对于300列和10行的情况来说...;-) - gbn

2
您是不是指的是使用select * from ...而不是select col1, col2, col3 from ...?我认为最好命名列并检索最少量的信息,因为:
  • 您的代码将独立于数据库中列的物理顺序工作。列顺序不应影响应用程序,但如果使用*,情况将是如此。在数据库迁移等情况下可能很危险。
  • 如果命名列,DBMS可以进一步优化执行。例如,如果存在包含您感兴趣的所有数据的索引,则根本不会访问表。
如果您所说的“通配符”有其他意思,请忽略我的回答...

那就是我所提到的情况,尽管我想看看除了执行计划之外可能会产生性能损耗的地方。不过,我同意你不使用它的原因。 - Geo Ego

1

编辑:如果你在谈论像 Select * From ... 中的星号通配符,那么请参考其他答案...

如果你在谈论谓词子句中的通配符,或者使用Like运算符的其他查询表达式,如下所述的(_ , % ),则:

这与使用通配符是否影响SQL是否“可搜索(SARG-ABLE)”有关。可搜索(SARGABLE,Search-ARGument-able)意味着查询的搜索或排序参数是否可以用作现有索引的入口参数。如果你在参数的开头添加通配符

 Where Name Like '%ing'

那么就没有办法遍历名称字段上的索引,以查找以“ing”结尾的节点。

如果您将通配符附加到末尾,则:

Where Name like 'Donald%' 

那么优化器仍然可以使用名称列上的索引,查询仍然是SARG-able


我应该更具体一些。我已经进行了编辑以做到这一点。我指的是SELECT *与SELECT列表之间的区别。然而,这个答案让我对一个我没有考虑过的问题有了一些见解。谢谢! - Geo Ego

0

如果你所谓的 SQL 通配符是 *,它本身并不会导致性能开销。然而,如果表被扩展,你可能会发现自己检索到你没有搜索的字段。 一般来说,在搜索或插入字段时不具体指定是一个坏习惯。 请考虑。

insert into mytable values(1,2)

如果表格扩展到三个字段会发生什么?


0

从执行计划的角度来看,这可能不需要更多的工作。但是,如果您获取了实际上不需要的列,则数据库和应用程序之间将使用额外的网络带宽。此外,如果您正在使用高级客户端API对返回的数据执行某些操作(例如Perl的selectall_hashref),那么这些额外的列将对客户端产生性能成本。有多少?这取决于情况。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接