我见过很多人声称你应该在选择查询中专门命名你想要的每一列.
假设我要使用所有列,为什么我不使用SELECT *
?
即使考虑问题*SQL查询 - 从视图中选择*或从视图*选择col1,col2,... colN,我不认为这是完全重复的,因为我从一个略微不同的角度来看待问题.
我们的原则之一是不要在它之前进行优化.考虑到这一点,似乎使用SELECT *
应该是首选方法,直到它被证明是一个资源问题或模式几乎是一成不变的.据我们所知,在开发完成之前不会发生这种情况.
那就是说,不使用是否有一个压倒一切的问题SELECT *
?
不过早优化的引用的本质是寻求简单直接的代码,然后使用分析器指出热点,然后您可以优化这些热点以提高效率.
当您使用select*时,您无法进行配置文件,因此您不会编写清晰明了的代码,而且您违背了引用的精神.select *
是一种反模式.
因此,选择列并不是一个不成熟的优化.我头顶的一些东西......
如果在SQL语句中指定列,则如果从表中删除该列并执行查询,则SQL执行引擎将出错.
您可以更轻松地扫描使用该列的代码.
您应该始终编写查询以恢复最少量的信息.
正如其他人提到的那样,如果您使用序数列访问,则不应使用select*
如果您的SQL语句连接表,则select*将为您提供连接中所有表的所有列
结果是使用select *
......
应用程序使用的列是不透明的
DBA及其查询分析器无法帮助您的应用程序的性能不佳
当发生变化时,代码更脆弱
您的数据库和网络正在遭受痛苦,因为它们带回了太多数据(I/O)
数据库引擎优化很小,因为无论是(逻辑)还是所有数据.
编写正确的SQL就像编写一样简单Select *
.因此,真正懒惰的人会编写正确的SQL,因为他们不想重新访问代码并尝试记住他们在执行时所做的事情.他们不想向DBA解释每一点代码.他们不想向他们的客户解释为什么应用程序像狗一样运行.
如果您的代码依赖于特定顺序的列,那么当表的更改时,您的代码将会中断.此外,当您选择*时,您可能从表中获取太多,特别是如果表中有二进制字段.
仅仅因为您现在使用所有列,并不意味着其他人不会在表中添加额外的列.
它还增加了计划执行缓存的开销,因为它必须获取有关表的元数据以了解*中的列.
一个主要原因是,如果您从表中添加/删除列,则进行SELECT*调用的任何查询/过程现在将获得比预期更多或更少的数据列.
以迂回的方式,你打破了尽可能使用严格打字的模块化规则.明确几乎普遍更好.
即使您现在需要表中的每一列,也可以在以后添加更多列,每次运行查询时都会将其删除,这可能会影响性能.它会伤害性能,因为
你正在通过网络提取更多数据; 和
因为你可能会破坏优化器将数据从索引中拉出来的能力(对于列中所有列的查询而言),而不是在表本身中进行查找
当您明确需要表中的每一列时,而不是需要表格中的每一列,而您需要在查询时查看.例如,如果正在编写需要显示表的全部内容的数据库管理应用程序(无论它们是什么),您可以使用该方法.
有几个原因:
如果数据库中的列数发生变化,并且您的应用程序希望有一定数量...
如果数据库中列的顺序发生变化,并且您的应用程序希望它们按特定顺序排列......
内存开销.8个不必要的INTEGER列会增加32个字节的浪费内存.这听起来不是很多,但这是针对每个查询而INTEGER是小列类型之一......额外的列更可能是VARCHAR或TEXT列,这会更快地加起来.
网络开销.与内存开销有关:如果我发出30,000个查询并且有8个不必要的INTEGER列,我浪费了960kB的带宽.VARCHAR和TEXT列可能会大得多.
注意:我在上面的例子中选择了INTEGER,因为它们具有4字节的固定大小.
如果您的应用程序使用SELECT*获取数据并且数据库中的表结构已更改(例如删除了一列),则应用程序将在您引用缺少字段的每个位置失败.如果您改为在查询中包含所有列,那么应用程序将在(最有希望)您最初获取数据的位置中断,从而使修复更容易.
话虽如此,有许多情况需要SELECT*.一种是我一直遇到的情况,我需要将整个表复制到另一个数据库(例如,SQL Server到DB2).另一种是通常写入显示表的应用程序(即,不知道任何特定的表).