【问题标题】:SQL query - Select * from view or Select col1, col2, ... colN from view [duplicate]SQL 查询 - 从视图中选择 * 或从视图中选择 col1、col2、... colN [重复]
【发布时间】:2010-09-12 19:21:49
【问题描述】:

我们使用的是 SQL Server 2005,但这个问题可以针对任何RDBMS

从视图中选择所有列时,以下哪项更有效?

Select * from view 

Select col1, col2, ..., colN from view

【问题讨论】:

标签: sql sql-server


【解决方案1】:

永远不要使用“SELECT *”!!!!

这是查询设计的基本规则!

这有多种原因。其中之一是,如果您的表上只有三个字段,并且您在调用查询的代码中使用了所有三个字段,那么随着应用程序的增长,您很可能会向该表添加更多字段,如果您的 select * 查询只是为了返回调用代码的这 3 个字段,然后您从数据库中提取的数据比您需要的要多。

另一个原因是性能。在查询设计中,不要像以下口头禅那样考虑可重用性:

尽你所能吃,但吃尽你所能。

【讨论】:

  • 你应该尝试使用“select *”的唯一一次是在exists()中,但不要!请改用“选择 1”。
  • @Even Mien:这取决于实现。一些 RDBMS 知道如何在 EXISTS() 谓词中优化 SELECT *,因此它甚至可以比 SELECT 1 更有效。了解我们的唯一方法是使用您的品牌和版本进行测试。
【解决方案2】:

最佳做法是按名称选择每一列。将来,您的数据库架构可能会更改为添加特定查询不需要的列。我建议按名称选择每一列。

【讨论】:

    【解决方案3】:

    只是为了澄清几个人已经提出的观点,Select * 效率低下的原因是因为必须先调用数据库以准确找出可用的字段,然后再调用查询的位置使用显式列。

    当您在调试、运行临时查询或处于开发查询的早期阶段时,请随意使用 Select *,但一旦您知道所需的列,请明确说明它们。

    【讨论】:

      【解决方案4】:

      选择 * 是一种糟糕的编程习惯。它既可能导致事物破裂,也可能使事物免于破裂。如果您只查询一个表或视图,则可能不会提高效率(尽管如果您不打算实际使用每个字段,也有可能)。如果您有一个内部连接,那么您至少有两个字段返回相同的数据(连接字段),因此您正在浪费网络资源将冗余数据发送回应用程序。一开始您不会注意到这一点,但随着结果集越来越大,您很快就会拥有一个已满且不需要的网络管道。我想不出 select * 能给你带来任何好处的例子。如果添加了一个新列,并且您不需要转到代码对其进行处理,那么根据定义,您的查询不应返回该列。如果有人删除并以不同的顺序重新创建列,那么您的所有查询都会显示错误的信息或给出错误的结果,例如将价格放入新记录中的部件号字段。

      此外,从对象浏览器中拖动列名也很快,所以这只是纯粹的懒惰而不是编码效率。

      【讨论】:

        【解决方案5】:

        这取决于。视图的继承是一件方便且易于维护的事情(SQL Anywhere):

        create view v_fruit as select F.id, S.strain from F key join S; 
        create view v_apples as select v_fruit.*, C.colour from v_fruit key join C;
        

        【讨论】:

        • 这是一个很好的例子,当 SELECT view.* FROM view 实际上是一个很好的实践。原因是因为我们可以有很多水果,每次我们的父类发生变化时改变都是一场噩梦,所以我同意这种方法,但是我不知道如果有的话这是否是一个好习惯是这些水果之上的一些报告层,当然假设我们总是需要来自 v_fruit 的所有列
        • 另外,如果由于某种原因列名被添加到 v_fruit 但任何 v_apples 或 v_pears 等中已经存在相同的名称,我们将在查询时收到错误,我知道这是一个设计问题,但这绝对是一个潜在的风险,有什么想法可以克服这个问题吗?
        【解决方案6】:

        如果您真的选择了所有列,那么无论您是要求 * 还是明确要求,都不会有任何明显的区别。 SQL 服务器将在几乎相同的时间内以相同的方式解析请求。

        【讨论】:

          【解决方案7】:

          始终从视图中选择 col1、col2 等。我知道的两种方法之间没有效率差异,但是使用“select *”可能很危险。如果您修改视图定义添加新列,您可以使用“select *”中断程序,而选择一组预定义的列(甚至所有列,命名)仍然有效。

          【讨论】:

            【解决方案8】:

            我想这完全取决于查询优化器的作用。

            如果我想获取行中的每条记录,我通常会使用“SELECT *...”选项,因为我不必担心是否应该更改底层表结构。同样,对于维护代码的人来说,看到“SELECT *”会告诉他们该查询旨在返回每一列,而单独列出这些列并不能传达相同的意图。

            【讨论】:

              【解决方案9】:

              为了性能 - 查看查询计划(应该没有区别)。

              为了可维护性。 - 始终提供一个字段列表(也适用于 INSERT INTO)。

              【讨论】:

                【解决方案10】:
                select 
                column1
                ,column2
                ,column3
                .
                .
                .
                from Your-View
                

                这个比使用

                更优化
                select *
                from Your View 
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2019-05-22
                  • 2013-09-17
                  • 2018-09-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多