【问题标题】:What are the potentially negative implications of using SELECT * in MySQL? [duplicate]在 MySQL 中使用 SELECT * 有哪些潜在的负面影响? [复制]
【发布时间】:2011-10-06 17:23:11
【问题描述】:

可能的重复:
Performance issue in using SELECT * ?
What is the reason not to use select *?

我记得前段时间读过一篇博客,其中详细介绍了使用星号选择 MySQL 中表的所有列的详细性能问题,但我再也找不到它了。我正在使用 MySQL 和 PHP 的 PDO 驱动程序(以及因此准备好的语句)的组合,星号自然会加速我的许多 SQL 查询的维护。

您认为使用星号是可以接受的做法吗?如果不是,您的原因是什么(安全/性能/标准方面)?

【问题讨论】:

标签: mysql performance security standards


【解决方案1】:

命名列而不是使用 * 的要点是:

  • 意图:您的程序可能应该知道您正在获取哪些列
  • 性能:为什么要从 mySql 传输到您不需要的程序列?这只会消耗带宽。

如果您知道需要所有列,那么您就满足上述两个条件。 这里没有什么神奇之处,只有好的软件开发。

但是,请记住,您的表模式可能会在您编写程序后发生变化。如果发生这种情况,您对 * 的使用开始违反意向标准。

【讨论】:

    【解决方案2】:

    比性能更重要的是清晰度。在某些源代码中阅读像 SELECT * 这样的语句绝对不会给我任何信息。要找出该查询的结果包含哪些列,我必须查看数据库文档(如果存在的话)或者必须查看数据库本身。

    我公司的编码风格需要完整的陈述,主要是因为这个原因。 INSERT INTO 必须包含列列表,SELECT * 是禁止的,例如按 1 分组或按 1 排序。

    【讨论】:

      【解决方案3】:

      有一个使用select *的问题列表。

      1 - 输出的一致性
      如果您的客户需要某些字段并且您更改了表的布局,select * 将在基础表更改时更改其输出,从而破坏您的客户端代码。

      2 - 网络性能
      如果您只需要输出中所有字段的子集,select * 将通过网络发送不需要的数据来浪费网络带宽。

      3a - 数据库性能
      在简单的表上select * 可能不会降低性能,但是如果你有 blob 字段(你不感兴趣)select * 也会获取这些字段,从而降低性能

      3b - 数据库服务器上的内存使用情况
      如果 MySQL 需要使用临时表,select * 将通过让 MySQL 在内存中存储更多数据来额外消耗服务器、磁盘、内存和 CPU。

      3c - 在 InnoDB 上不能使用覆盖索引
      在 InnoDB 上,如果您选择索引的字段,MySQL 永远不需要读取实际的表数据,它只是直接从索引中读取信息,select * 杀死了这个优化。

      4 - 代码清晰
      select * 不会向查询的读者提供有关将从服务器检索哪些字段的信息。 select name, address, telephone from ... 让我们立即清楚我们正在处理的数据。
      如果您的桌子在祖鲁语中,您甚至可以这样做

      select
        igama as name
        ikheli as address
        ....
      

      对于 99.7% 不说祖鲁语的人来说,这比原来的名字有用得多。

      5 - 不要破解代码,精心编写代码
      选择 * 只是一个快速的技巧,可以让东西正常工作。
      但是,当您编写代码时,您应该知道自己在做什么,明确说明,选择您需要的内容,如果需要,使用别名为字段赋予有意义的名称。
      调整您的代码以仅选择您需要的内容。
      如果我在代码审查中看到select *,我会将其标记为看不见,因为这是代码异味。

      希望这会有所帮助。

      【讨论】:

      • 谢谢,最彻底的回答。
      猜你喜欢
      • 2011-02-24
      • 2014-12-08
      • 1970-01-01
      • 1970-01-01
      • 2010-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-18
      相关资源
      最近更新 更多