为什么SELECT *是不好的做法?如果您添加了想要的新列,这难道不意味着需要更改的代码更少吗?
我知道SELECT COUNT(*)在某些db上是一个性能问题,但是如果您真的想要每个列呢?
为什么SELECT *是不好的做法?如果您添加了想要的新列,这难道不意味着需要更改的代码更少吗?
我知道SELECT COUNT(*)在某些db上是一个性能问题,但是如果您真的想要每个列呢?
当前回答
还有一个更实际的原因:钱。当你使用云数据库时,你必须为数据处理付费,没有任何解释来读取你将立即丢弃的数据。
例如:BigQuery:
查询价格 查询定价是指运行SQL命令和用户定义函数的成本。BigQuery根据一个指标对查询收费:处理的字节数。
和控制投影-避免选择*:
最佳实践:控制投影—只查询所需的列。 投影指的是查询读取的列数。投影多余的列会导致额外的(浪费的)I/O和物化(写入结果)。 使用SELECT *是最昂贵的查询数据的方法。当您使用SELECT *时,BigQuery会对表中的每一列进行全面扫描。
其他回答
引用自这篇文章。
永远不要用“SELECT *”,
我发现使用“SELECT *”的原因只有一个。
如有特殊要求和创建动态环境时添加或删除列,由应用程序代码自动处理。在这种特殊情况下,您不需要更改应用程序和数据库代码,这将自动影响生产环境。在这种情况下,您可以使用“SELECT *”。
可以把它看作是减少应用程序和数据库之间的耦合。
总结一下“代码气味”方面: SELECT *在应用程序和模式之间创建一个动态依赖关系。限制它的使用是使依赖更加明确的一种方法,否则对数据库的更改更有可能使应用程序崩溃。
在设计方案之前理解您的需求(如果可能的话)。
了解数据, 1)索引 2)所使用的存储类型; 3)供应商引擎或功能;即……缓存,内存功能 4)数据类型 5)桌子大小 6)查询频率 7)如果资源是共享的,相关的工作量 8)测试
A)要求会有所不同。如果硬件不能支持预期的工作负载,则应该重新评估如何在工作负载中提供需求。关于向表中添加的列。如果数据库支持视图,您可以使用特定的命名列创建特定数据的索引(?)视图(vs.选择'*')。定期检查您的数据和模式,以确保您永远不会遇到“输入垃圾”->“输出垃圾”综合征。
假设没有其他解;你可以考虑以下几点。一个问题总是有多种解决方案。
1)索引:select *将执行一个表罐。根据各种因素,这可能涉及到磁盘寻道和/或与其他查询的争用。如果表是多用途的,请确保所有查询都是高性能的,并在您的目标时间以下执行。如果有大量数据,而您的网络或其他资源没有调优;你需要考虑到这一点。数据库是一个共享环境。
2)存储类型。Ie:如果你使用SSD,磁盘或内存。I/O时间和系统/cpu上的负载会有所不同。
3) DBA是否可以调优数据库/表以获得更高的性能?假设出于某种原因,团队已经决定选择“*”是问题的最佳解决方案;可以将DB或表加载到内存中。(或者其他方法…也许反应被设计成有2-3秒的延迟?——而广告的作用是为公司赚取收入……)
4)从基线开始。了解您的数据类型,以及如何显示结果。更小的数据类型、字段数量会减少结果集中返回的数据量。这将为其他系统需求留下可用资源。系统资源通常是有限制的;“总是”工作低于这些限制,以确保稳定性和可预测的行为。
5)表/数据的大小。选择“*”在小表中很常见。它们通常适合内存,并且响应时间很快。再次……回顾您的需求。特征蠕变计划;总是为当前和未来可能的需求做计划。
6)查询/查询频率。了解系统上的其他工作负载。如果这个查询每秒发出一次,并且表很小。结果集可以设计为保留在缓存/内存中。然而,如果查询是一个频繁的批处理过程,有千兆字节/兆兆字节的数据……最好分配额外的资源以确保其他工作负载不受影响。
7) Related workloads. Understand how the resources are used. Is the network/system/database/table/application dedicated, or shared? Who are the stakeholders? Is this for production, development, or QA? Is this a temporary "quick fix". Have you tested the scenario? You'll be surprised how many problems can exist on current hardware today. (Yes, performance is fast...but the design/performance is still degraded.) Does the system need to performance 10K queries per second vs. 5-10 queries per second. Is the database server dedicated, or do other applications, monitoring execute on the shared resource. Some applications/languages; O/S's will consume 100% of the memory causing various symptoms/problems.
8)测试:测试你的理论,尽可能多地理解。你选择的“*”问题可能是一个大问题,或者它可能是你甚至不需要担心的事情。
我不认为这真的可以有一个通用的规则。在许多情况下,我避免使用SELECT *,但我也使用过SELECT *非常有用的数据框架。
和所有事情一样,有收益也有成本。我认为收益与成本的等式的一部分是你对数据结构有多少控制。在SELECT *工作良好的情况下,数据结构受到严格控制(它是零售软件),因此没有太大的风险,有人会将一个巨大的BLOB字段发送到表中。
使用列名进行选择提高了数据库引擎从索引访问数据的可能性,而不是查询表数据。
当数据库模式发生变化时,SELECT *使您的系统暴露在意想不到的性能和功能变化中,因为您要将任何新列添加到表中,即使您的代码还没有准备好使用或显示这些新数据。