为什么我们不应该在生产服务器上的mysql查询中使用Select *?

时间:2012-04-10 08:05:35

标签: mysql select pdo

基于这个问题Selecting NOT NULL columns from a table其中一张海报说

  

你不应该在生产中使用SELECT *。

我的问题:我们不应该在生产服务器上的mysql查询中使用Select *吗?如果是,为什么我们不应该选择全部?

3 个答案:

答案 0 :(得分:3)

大多数人建议不要在生产中使用SELECT *,因为它往往会破坏事物。但也有一些例外。

  • SELECT *获取所有列 - 而大部分时间则不提取 需要他们所有。这会导致SQL服务器发送的列数多于 需要,这是一种浪费,使系统变慢。
  • 使用SELECT *,稍后添加列时,旧查询也将如此 选择这个新列,通常它不需要它。命名 这些列明确地阻止了这一点。
  • 大多数撰写SELECT *查询的人也倾向于抓住行 并使用列顺序来获取列 - 这将破坏您的代码 一旦在现有列之间注入列。
  • 明确命名列也可以保证它们始终处于相同的顺序,而SELECT *在修改表列顺序时可能会有不同的行为。

但也有例外,例如这些陈述:

INSERT INTO table_history
SELECT * FROM table 

这样的查询从表中获取行,并将它们插入table_history。如果您希望此查询在将新行添加到表和table_history时继续工作,SELECT *是可行的方法。

答案 1 :(得分:3)

请记住,您的数据库服务器不一定与查询数据库的程序位于同一台计算机上。数据库服务器可能位于带宽有限的网络上;它甚至可能在全世界的中途。

  • 如果您确实需要每一列,那么请务必执行SELECT * FROM table
  • 但是,如果您只需要某些列,那么使用SELECT * FROM table请求所有列只会丢弃一半的列会浪费带宽。

指定您想要的确切列可能很好的其他潜在原因:

  • 数据库结构可能会发生变化。如果您的程序采用某些列名称,那么例如,如果列名称发生更改,则可能会失败。如果违反了有关列名的假设,则明确命名要检索的列将使程序立即失败。
  • 正如@Konerak所提到的,命名所需的列也可确保结果中列的顺序相同,即使表架构发生更改(即插入一列) - 在另外两个人之间。)如果你依赖于FirstName作为结果的[2]元素,这一点非常重要。

    (注意:处理此问题的更强大和自我记录的方法是将数据库结果作为键值对列表,例如PHP关联数组,Perl哈希或Python dict这样你就不需要使用数字来索引结果(name = result[2]) - 而是可以使用列名:name = result["FirstName"]。)

答案 2 :(得分:0)

使用SELECT *的效率非常低,尤其是对于包含大量列的表。您应该只选择所需的列。

除此之外,使用列名使查询更易于阅读和维护。