为什么 SELECT * 被认为是有害的?

2023-12-27

Why is SELECT *不好的做法?如果您添加了所需的新列,这不是意味着要更改的代码会更少吗?

我明白那个SELECT COUNT(*)在某些数据库上是一个性能问题,但是如果您真的想要每一列怎么办?


其实主要有以下三个原因:

  • 将数据传输给消费者的效率低下。当您 SELECT * 时,您通常会从数据库中检索比应用程序实际运行所需的列多的列。这会导致更多数据从数据库服务器移动到客户端,从而减慢访问速度并增加计算机负载,并花费更多时间在网络上传输。当有人向基础表添加新列时尤其如此,而这些新列在原始使用者对其数据访问进行编码时并不存在且不需要。

  • 索引问题。考虑这样一个场景:您想要将查询调优到较高的性能水平。如果您要使用 *,并且它返回的列数多于您实际需要的列数,则服务器通常必须执行比其他方式更昂贵的方法来检索数据。例如,您将无法创建一个仅覆盖 SELECT 列表中的列的索引,即使您这样做了(包括所有列 [shudder]),下一个向基础表添加列的人将导致优化器忽略优化的覆盖索引,并且您可能会发现查询的性能会在没有明显原因的情况下大幅下降。

  • 绑定问题。当您 SELECT * 时,可以从两个不同的表中检索同名的两列。这通常会使您的数据使用者崩溃。想象一个连接两个表的查询,两个表都包含一个名为“ID”的列。消费者如何知道哪个是哪个?当底层表结构发生变化时,SELECT * 也会混淆视图(至少在某些版本的 SQL Server 中)——视图没有重建,返回的数据可能是无意义的 http://www.mssqltips.com/tip.asp?tip=1427。最糟糕的是,您可以按照自己的意愿命名您的列,但下一个出现的人可能无法知道他必须担心添加一个列会与您已经开发的列相冲突名称。

但这对于 SELECT * 来说也不全是坏事。我在这些用例中大量使用它:

  • 即席查询。当尝试调试某些东西时,尤其是在我可能不熟悉的狭窄表上调试时,SELECT * 通常是我最好的朋友。它可以帮助我了解正在发生的情况,而无需对底层列名称进行大量研究。列名越长,“加号”就越大。

  • 当*表示“一行”时。在以下用例中,SELECT * 就很好,关于它是性能杀手的传言只是都市传说,多年前可能有一定的道理,但现在不行了:

    SELECT COUNT(*) FROM table;
    

    在这种情况下,* 表示“计算行数”。如果您要使用列名而不是 * ,它将计算该列的值不为空的行。 COUNT(*),对我来说,真正让你明白了你正在计数的概念rows,并且您可以避免由于从聚合中消除 NULL 而导致的奇怪边缘情况。

    这种类型的查询也是如此:

    SELECT a.ID FROM TableA a
    WHERE EXISTS (
        SELECT *
        FROM TableB b
        WHERE b.ID = a.B_ID);
    

    在任何有价值的数据库中,* 只意味着“一行”。在子查询中输入什么内容并不重要。有些人在 SELECT 列表中使用 b 的 ID,或者他们会使用数字 1,但在我看来,这些约定几乎是无意义的。你的意思是“计算行数”,这就是 * 的含义。大多数查询优化器都足够聪明,知道这一点。 (虽然说实话,我只是know对于 SQL Server 和 Oracle 来说也是如此。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 SELECT * 被认为是有害的? 的相关文章

  • 如何停止在 mongodb 集合中插入重复文档

    让我们有一个MongoDB包含三个文档的集合 db collection find id user A title Physics Bank Bank A id user A title Chemistry Bank Bank B id u
  • SQL:如何在按部分分组的查询中使用子查询?

    如何在按部分分组的查询中使用子查询 我使用 SQL Server 2008 R2 和 Delphi 2010 我收到此错误 Cannot perform an aggregate function on an expression cont
  • 需要按天分割日期时间范围

    我有一个需要根据日期时间拆分的表 输入表 ID Start End A 2019 03 04 23 18 04 2019 03 04 23 21 25 A 2019 03 04 23 45 05 2019 03 05 00 15 14 所需
  • SQL 中基于下一条记录和上一条记录的复杂排序

    这是一个后续问题根据 SQL 中的下一条记录和上一条记录进行排序 https stackoverflow com questions 30477803 sorting based on next and previous records i
  • SQL 查询用于计算每个客户的订单数量和总金额

    我有两张桌子Order与列 OrderID OrderDate CID EmployeeID And OrderItem与列 OrderID ItemID Quantity SalePrice 我需要返回客户 ID CID 每个客户的订单数
  • SQL Join 列上类似于另一列[重复]

    这个问题在这里已经有答案了 可能的重复 mysql连接查询使用like https stackoverflow com questions 1930809 mysql join query using like 我想要进行连接 其中一列包含
  • 数据库表设计

    我在选择数据库表的变量类型时遇到问题 有人可以给我一些关于如何选择类型的一般准则吗 以下是我的一些问题 用户 ID 应该是什么 INT 看起来很小 因为设计时应该考虑到大量用户 那么如果不是 INT 还有什么呢 大整数 VARCHAR 难道
  • 我应该用不可变或可变的数据结构来表示数据库数据吗?

    我目前正在使用 Scala 进行编程 但我想这适用于任何函数式编程语言 或者更确切地说 任何建议不变性并可以与数据库交互的编程语言 当我从数据库中获取数据时 我将其映射到模型数据结构 在函数式编程中 数据结构往往是不可变的 但是数据库中的数
  • 如何通过子 POJO 的属性过滤复合 ManyToMany POJO?

    我有两个像这样的房间实体 Entity public class Teacher implements Serializable PrimaryKey autoGenerate true public int id ColumnInfo n
  • 快速查询最新记录的方法?

    我有一张这样的表 USER PLAN START DATE END DATE 1 A 20110101 NULL 1 B 20100101 20101231 2 A 20100101 20100505 在某种程度上 如果END DATE i
  • 如何使用 django ORM 在外键字段上连接两个表?

    假设我有以下模型 class Position models Model name models CharField class PositionStats models Model position models ForeignKey P
  • 提高第一个查询的性能

    如果执行以下数据库 postgres 查询 则第二次调用要快得多 我猜第一个查询很慢 因为操作系统 linux 需要从磁盘获取数据 第二个查询受益于文件系统级别和 postgres 中的缓存 有没有一种方法可以优化数据库以快速获得结果fir
  • 使用子查询 select 创建新表

    我试图从子查询选择创建一个新表 但出现以下错误 附近的语法不正确 SELECT INTO foo FROM SELECT DATEPART MONTH a InvoiceDate as CalMonth DATEPART YEAR a In
  • 如何识别拼写不同的相似单词

    我想从数据库中过滤掉重复的客户名称 一位客户可能有多个同名但拼写差异不大的系统条目 这是一个示例 名为 Brook 的客户可能有 3 个系统条目 有了这个变化 布鲁克 贝尔塔 布鲁克 贝尔塔 比鲁克 贝尔塔 假设我们将此名称放入一个数据库列
  • 日期语句之间的 JPQL SELECT [关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我想将此 SQL 语句转换为等效的 JPQL SELECT FROM events WHERE events date BETWE
  • 无法在 Sqlite3 中添加默认值为 NULL 的 NOT NULL 列

    尝试将 NOT NULL 列添加到现有表时出现以下错误 为什么会发生这种情况 我尝试了 rake db reset 认为现有记录是问题所在 但即使重置数据库后 问题仍然存在 你能帮我解决这个问题吗 迁移文件 class AddDivisio
  • 什么是时序数据库?

    What is 时间序列数据库例如InfluxDB 我应该何时 何地使用它 请给我它的业务场景示例 检查wiki https en wikipedia org wiki Time series database 时间序列数据库 TSDB 是
  • 快速将列的副本添加到 MySQL 表

    我需要一种快速的方法来复制表中的 DATETIME 列并为其指定一个新名称 我的表中有一个名为 myDate 的列 名为 myResults 我需要一个查询来在名为 newDate 的表中创建一个新列 该列的数据与 myDate 列完全相同
  • 如何通过SQL查询检查是否有JSON函数?

    有SQL 2016 中的 JSON 函数 https learn microsoft com en us sql t sql functions json functions transact sql例如 JSON VALUE JSON Q
  • 如何部署“SQL Server Express + EF”应用程序

    这是我第一次部署使用 SQL Server Express 数据库的应用程序 我首先使用实体 框架模型来联系数据库 我使用 Install Shield 创建了一个安装向导来安装应用程序 这些是我在目标计算机中安装应用程序所执行的步骤 安装

随机推荐

  • Angular - 如何导入 googleapis 库?

    我正在尝试将 Google Drive API 合并到我的一个项目中 Node js快速入门指南 https developers google com drive api v3 quickstart nodejs要求我导入文件读取和 go
  • 是否存在无法避免 lambda 中的尾随返回类型语法的情况?

    关于之前的问题 是否可以通过 lambda 引用返回 T 类型的对象 而不使用尾随返回类型语法 q 40977730 我想知道是否还有其他重要的案例或例子尾随返回类型语法 当使用 lambda 时 可以not应避免 在 C 14 中 一个有
  • 在 MATLAB 中将 repmat 替换为 bsxfun

    在下面的函数中 我想进行一些更改以使其更快 它本身很快 但我必须在 for 循环中多次使用它 所以需要很长时间 我想如果我用 bsxfun 替换 repmat 会使其更快 但我不确定 我该如何进行这些替换 function out lagc
  • 当 onCreate 中完成 Activity 时,我的 Fragment 的 onCreateView 在 onCreate 之前如何被调用?

    这很奇怪 我有一个简单的应用程序 登录后会显示活动中的片段 该应用程序还有一个不活动的 超时 在此时间后它会完成活动并显示登录屏幕 如果应用程序在超时发生时处于后台 那么当下一次超时时onCreate or onStart事件发生在它完成的
  • 在哪里可以找到 FCM Firebase 注册 ID(在 PHP 中,对于 Ionic 框架)?

    我们已经使用 Ionic 框架构建了一个应用程序 我们是 Ionic 等的初学者 并将设备注册到我们的 Firebase 帐户 以便我们可以发送推送消息 我现在找到了一个通过 cURL 连接到 fcm 的 PHP 片段 我可以设置消息和标题
  • 实现阶乘函数时出现“所有控制路径递归”错误

    对于课堂 我有一个作业 编写一个 C 程序 输出您可以选择的不同方式的数量k一组中的对象n对象 两者n and k应为正整数 该数字由以下公式给出 C n k n k n k 您的程序应该使用两个返回值的函数 第一个应该叫factorial
  • 为什么来自类的java字节码出现新静态内部类的代码出现jvm指令ACONST_NULL

    我尝试新建一个内部静态类 但我发现字节码出现了jvm指令ACONST NULL bwteen NEW DUP and INVOKE SPECIAL 但我知道一门新课是 NEW DUP 调用 特殊 package com hoho api a
  • 自定义 Jackson 对象映射器

    我有一个用例 需要维护两组 JSON 输出 一组具有漂亮的 JSON 属性名称 另一组没有 因此 我决定自定义 ObjectMapper 以便它忽略字段上的 JsonProperty pretty name 注释并使用字段属性名称 在这种情
  • SQL内联if语句类型问题

    我想做一个 MS SQL 查询 返回如下内容 Col1 Col2 Col3 AAA 18 92 18 92 BBB 20 00 40 00 AAA 30 84 30 84 BBB 06 00 12 00 AAA 30 84 30 84 AA
  • 在服务器端java类中读取客户端时区

    我有一个客户端程序 它将时间发送到服务器端程序 我正在使用 Callendar 对象将时间值从客户端传递到服务器 我的客户端程序位于斯里兰卡 服务器位于英国 当我在客户端发送时间 例如 2011 11 21T12 43 41 352 05
  • 如何读取UTF-8的InputStream?

    欢迎大家 我正在开发一个 Java 应用程序 它从互联网调用 PHP 它给我一个 XML 响应 响应中包含这个词 Pr ximo 但是当我解析 XML 的节点并将响应获取到字符串变量中时 我收到这样的词 Pr ximo 我确信问题是我在 J
  • 如何绑定到“MvxLinearLayout”的“ItemClick”?

    我有一个ScrollView最初包裹着两个MvxListView控制 Having ListView控制在一个ScrollView不过 Android 不支持 这是有道理的 因为它们都尝试填充父高度并提供自己的滚动逻辑 我想要的是两个不可滚
  • 使用核心数据实现枚举的最佳方法

    将核心数据实体绑定到枚举值以便我能够为实体分配类型属性的最佳方法是什么 换句话说 我有一个名为Item与itemType我想要绑定到枚举的属性 最好的方法是什么 如果您想将值限制为枚举 则必须创建自定义访问器 因此 首先您需要声明一个枚举
  • 在 C++ 中使用友元函数

    刚刚阅读了有关友元函数的内容 我正在尝试使用 B 类中的友元函数 Print 访问 A 类中的私有变量 number 我正在使用 Visual Studio 我的代码的编译给了我很多不同的错误 例如 C2011 A class 类型重新定义
  • 无法访问作业跟踪器的 hadoop web ui [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我正在尝试
  • 在 javascript 的 google 地图 api 中显示楼层选择器

    当使用 Android 或 iOS 版 Google 地图 API 时 似乎默认启用室内地图 并且当您放大具有室内地图的建筑物时 楼层选择器 控件会自动出现 如何在 Google Maps API for javascript 中获得类似的
  • 使用 ServiceStack.ORMLite 的存储库模式中的事务

    我正在使用 ServiceStack ORMLite 实现存储库模式 如下所示 public class MyRepository IMyRepository private IDbConnectionFactory DbConnectio
  • 为什么矢量化失败?

    我想使用优化我的矢量化代码 msse2 ftree vectorizer verbose 2 我有以下简单的代码 int main int a 2048 b 2048 c 2048 int i for i 0 i lt 2048 i b i
  • 是否有符合 W3C CR(显示:flex 等)的当前 CSS 灵活框布局模块的 Polyfill? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 Flexiejs com http flexiejs com 具有用于 CSS Flex 框的浏览器
  • 为什么 SELECT * 被认为是有害的?

    Why is SELECT 不好的做法 如果您添加了所需的新列 这不是意味着要更改的代码会更少吗 我明白那个SELECT COUNT 在某些数据库上是一个性能问题 但是如果您真的想要每一列怎么办 其实主要有以下三个原因 将数据传输给消费者的