选择 * SQL查询 vs 选择特定列的SQL查询

6

可能是重复问题:
为什么SELECT *被认为是有害的?

这可能是一个数据库初学者的问题。

我们的应用程序有一个像下面这样的表:

TABLE WF

Field              | Type        | Null | Key | Default | Extra          |
+--------------------+-------------+------+-----+---------+----------------+
| id                 | int(11)     | NO   | PRI | NULL    | auto_increment | 
| children           | text        | YES  |     | NULL    |                | 
| w_id               | int(11)     | YES  |     | NULL    |                | 
| f_id               | int(11)     | YES  |     | NULL    |                | 
| filterable         | tinyint(1)  | YES  |     | 1       |                | 
| created_at         | datetime    | YES  |     | NULL    |                | 
| updated_at         | datetime    | YES  |     | NULL    |                | 
| status             | smallint(6) | YES  |     | 1       |                | 
| visible            | tinyint(1)  | YES  |     | 1       |                | 
| weight             | int(11)     | YES  |     | NULL    |                | 
| root               | tinyint(1)  | YES  |     | 0       |                | 
| mfr                | tinyint(1)  | YES  |     | 0       |                | 
+--------------------+-------------+------+-----+---------+----------------+

这个表格预计会有超过一千万条记录。架构不会有太多变化。我需要检索 f_id、children、status、visible、weight、root、mfr 这些列。
哪种方法可以更快地检索数据?
1)Select * from WF where w_id = 1 AND status = 1; 我将在应用层中删除不必要的列。
2)Select children,f_id,status,visible,weight,root,mfr from WF where w_id = 1 AND status = 1; 在查询中预先选择了不必要的列,因此无需删除。
是否有任何真实的基准测试可以证明哪种方法更快?我知道有人说选择*是邪恶的,但是在尝试获取整个块而不是检索选择性列时,MySQL是否会更快地响应?
我正在使用 MySQL 版本:5.1.37-1ubuntu5(Ubuntu),应用程序是 Rails3 应用程序。

7
你拥有一张一千万条记录的表格;相较于你的基准标准,还能更贴近现实生活吗?请问需要翻译什么其他内容吗? - JeffO
@Chuck - 我同意我需要数据,但在另外几周之前这不会发生,我需要立即继续我的查询。 - paddle42380
即使您没有1000万行数据,也可以在暂存环境中生成虚拟数据进行测试。http://www.generatedata.com/ - p.campbell
1
@p.campbell等人:过于急于关闭问题的人——“重复”问题太笼统了,而这个问题具有特定的场景、特定的结构和容量以及特定的关系型数据库(MySQL)。更不用说应用程序框架(Ruby)了。对于这个问题可以得出非常详细的具体答案。 - RichardTheKiwi
1
@p.c 我不同意。这个问题不是关于可维护性、健壮性、标准、(反)模式的,而只是简单地问“哪种方法在数据检索方面更快?”还有其他关于(C领域)如何最快地完成某些事情的问题,答案可能是ASM(而不是漂亮的C),这才是正确的答案。链接的“重复”讨论的是广泛的理论和最佳实践。 - RichardTheKiwi
显示剩余4条评论
2个回答

5
作为一个列子,如果查询语句只包含一部分列,可以显著提高查询速度,因为可以使用仅包含这些列的索引,从而可能实现更好的查询性能。

点赞提到覆盖索引。我来这里就是为了说这个。 - Nathan DeWitt
谢谢,我已经了解了关于覆盖索引的要点。 - paddle42380
@papdel 这个查询的覆盖索引将涉及8列(共12列),并且维护起来会非常昂贵(相对度量)。 - RichardTheKiwi
谢谢Richard。我对所有突然的反弹都感到太兴奋了! - paddle42380
@Richard,这取决于插入和查询的比例。如果查询次数远远超过插入次数,即使是8中的12个覆盖索引也可能很值得。此外,8中的12列只是一个例子,我给出了一个针对一般问题的一般答案。 - Michael Goldshteyn
@Mic,这就是为什么我反对基于重复的理由关闭问题。虽然链接的问题已经详细回答了你的一般性问题,但是指标可能与问题的具体情况不相关。如果有什么问题,那么这个问题应该被关闭为“过于局限”,而不是“重复”。 - RichardTheKiwi

0
如果您返回的列较少,则网络传输的数据量就会减少,数据库处理的数据也会减少,因此查询速度几乎总是更快的。使用select *时,数据库通常会变得更慢,因为数据库需要找出哪些列,从而比指定列时做更多的工作。此外,如果结构发生重大变化,select *通常会返回错误的结果。它可能会显示用户不想看到的字段,或者如果有人愚蠢到重新排列列,那么应用程序实际上可能会以错误的顺序显示东西,或者如果从数据中进行插入,则将其放在错误的列中。在生产代码中使用selct *几乎总是一个不好的做法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接