鉴于您的说明您正在选择所有列,因此此时几乎没有区别。然而,要意识到数据库模式确实发生了变化。如果您使用 SELECT *,您将获得添加到表中的任何新列,即使您的代码很可能还没有准备好使用或呈现这些新数据。这意味着您将系统暴露在意外的性能和功能变化中。
您可能愿意将此视为一笔不小的成本,但要意识到您不需要的列仍然必须是:
- 从数据库中读取
- 通过网络发送
- 编组到您的流程中
- (对于 ADO 类型的技术)保存在内存中的数据表中
- 忽略和丢弃/垃圾收集
第 1 项有许多隐藏的成本,包括消除一些潜在的覆盖索引、导致数据页面加载(和服务器缓存抖动)、导致本可以避免的行/页面/表锁定。
将此与指定列与 * 的潜在节省进行平衡,唯一潜在的节省是:
- 程序员无需重新访问 SQL 即可添加列
- SQL 的网络传输更小/更快
- SQL Server 查询解析/验证时间
- SQL Server 查询计划缓存
对于第 1 项,实际情况是您将添加/更改代码以使用您可能添加的任何新列,所以这是一个清洗。
对于第 2 项,差异很少足以将您推入不同的数据包大小或网络数据包数量。如果您到了 SQL 语句传输时间是主要问题的地步,您可能需要首先降低语句速率。
对于第 3 项,由于 * 的扩展无论如何都必须发生,这意味着无论如何都要咨询表架构,因此不会节省任何费用。实际上,列出列将产生相同的成本,因为它们必须针对架构进行验证。换句话说,这是一次彻底的清洗。
对于第 4 项,当您指定特定列时,您的查询计划缓存可能会变大,但仅如果您正在处理不同的列集(这不是您指定的)。在这种情况下,您确实需要不同的缓存条目,因为您需要根据需要使用不同的计划。
因此,由于您指定问题的方式,这一切都归结为面对最终架构修改时的问题弹性。如果您将此模式刻录到 ROM 中(发生这种情况),那么 * 是完全可以接受的。
但是,我的一般指导原则是您应该只选择您需要的列,这意味着有时看起来您正在要求所有这些列,但是 DBA 和架构演变意味着一些可能会出现新的列,这可能会极大地影响查询。
我的建议是您应该始终选择特定列。请记住,您会一遍又一遍地擅长自己的工作,因此请养成正确做事的习惯。
如果您想知道为什么架构可能会在不更改代码的情况下发生更改,请考虑审计日志、生效/到期日期以及 DBA 为系统性地解决合规性问题而添加的其他类似内容。另一个不正当更改的来源是系统其他地方或用户定义字段中性能的非规范化。