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(使用前将#替换为@)