【问题标题】:What implication does select * from foo have? [duplicate]select * from foo 有什么含义? [复制]
【发布时间】:2011-03-04 14:28:25
【问题描述】:

可能重复:
Can select * usage ever be justified?

很想从具有更多 DBA 洞察力的人那里听到这一点,但是当您看到如下查询时,应用程序会面临哪些性能影响:

select * from some_large_table;

您必须进行全表扫描,因为没有命中索引,我相信如果我们说的是 O 表示法,我们在这里说的是 O(N),其中 N 是表的大小。这通常被认为不是最佳行为吗?如果您确实在某些时候确实需要桌子上的所有东西怎么办?是的,我们有分页等工具,但我在这里严格从数据库的角度来讨论。这种行为通常是不被接受的吗?

【问题讨论】:

  • 通常,当涉及到数据库时,大 O 表示法是指磁盘 IO 的数量,而不是算术运算
  • 抛开性能影响不谈,我绝不推荐使用select * from ...。为什么?您的查询不是未来的证明。假设您今天有 4 列。您期望查询中有 4 列。现在想象在未来的某一天,一列被添加或删除,甚至两列在该表中被交换。所有的地狱都可能破裂。因此,最好在您的selects 中明确说明您需要的所有列。不多也不少。
  • @Armen Tsirunyan:可讨论的观点。精心设计和调优的服务器将始终将索引保存在内存中。因此,即使没有执行磁盘 IO,从 B-Tree 索引中获取内容仍然需要 O(logN)。
  • @zerkms:确实可以讨论,这就是我写“通常”的原因:)
  • @darioo:列交换。所以?使用名称而不是位置指向列。

标签: mysql sql database


【解决方案1】:

如果不指定列,DB Engine 必须查询主表数据以获取列列表。此查询非常快,但会导致较小的性能问题。只要您不使用 JOIN 语句或嵌套查询进行草率的 SELECT *,就可以了。但是,请注意让 DB 引擎执行查询以查找列对性能的影响很小。

【讨论】:

  • "如果不指定列,DB Engine 必须查询主表数据以获取列列表。" - - 所以呢?当您获取整个表格时,这不是瓶颈。我什至没有提到表元信息几乎总是缓存在内存中。
【解决方案2】:

MySQL 服务器在服务器端打开一个游标来读取该表。查询的客户端可能不读取或读取所有记录,客户端的性能将仅取决于它实际获取的记录数。此外,服务器端查询的性能实际上可能比某些条件下的查询更快,因为它还涉及一些索引读取。只有当客户端获取所有记录时,才相当于全表扫描。

【讨论】:

    【解决方案3】:
    1. 选择比您需要的更多的列 (select *) 总是不好的。不要做超过你必须做的事情
    2. 如果您从整个表中进行选择,那么是否有索引并不重要。

    您将遇到的其他一些问题是您希望如何锁定表。如果这是一个繁忙的应用程序,您可能不希望完全阻止锁定,因为可能会返回不一致的数据。但是如果你锁得太紧,它可能会进一步减慢查询速度。 O(n) 在任何计算机科学应用程序中都被认为是可以接受的。然而,在数据库中,我们测量时间和读/写次数。这是大量的读取,可能需要很长时间才能执行。因此这是不可接受的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-28
      • 2011-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-19
      • 2019-06-07
      相关资源
      最近更新 更多