为何使用Select Top 100%?

时间:2009-10-26 02:49:52

标签: sql sql-server tsql

据我所知,在 SQL Server 2005 之前,您可以“欺骗”SQL Server以允许在视图定义中使用订单,同时在TOP 100 PERCENT > SELECT 子句。但是我已经看到了我继承的其他代码,它在动态SQL语句中使用SELECT TOP 100 PERCENT ...(在 ASP.NET 应用程序中使用 ADO 等) 。这有什么理由吗?结果是否与相同,包括TOP 100 PERCENT

10 个答案:

答案 0 :(得分:50)

它用于“intermediate materialization (Google search)

好文章:Adam Machanic: Exploring the secrets of intermediate materialization

他甚至提出了an MS Connect所以可以用更清洁的方式完成

我的观点是“本身并不坏”,但除非100%确定,否则不要使用它。问题是,它只在您执行此操作时才有效,可能不会更晚(补丁级别,架构,索引,行数等)......

工作示例

这可能会失败,因为您不知道评估事项的顺序

SELECT foo From MyTable WHERE ISNUMERIC (foo) = 1 AND CAST(foo AS int) > 100

这也可能因为

而失败
SELECT foo
FROM
    (SELECT foo From MyTable WHERE ISNUMERIC (foo) = 1) bar
WHERE
    CAST(foo AS int) > 100

但是,这在SQL Server 2000中没有。内部查询被评估并假脱机:

SELECT foo
FROM
    (SELECT TOP 100 PERCENT foo From MyTable WHERE ISNUMERIC (foo) = 1 ORDER BY foo) bar
WHERE
    CAST(foo AS int) > 100

注意,这仍然适用于SQL Server 2005

SELECT TOP 2000000000 ... ORDER BY...

答案 1 :(得分:39)

TOP(100)PERCENT在SQL Server的最新版本中完全没有意义,查询处理器会忽略它(以及在视图定义或派生表的情况下相应的ORDER BY)。

你是对的,从前,它可以作为一种技巧,但即便如此,它也不可靠。可悲的是,微软的一些图形工具将这个毫无意义的条款放入其中。

至于为什么这可能出现在动态SQL中,我不知道。你没有理由这是正确的,如果没有它,结果是一样的(同样,在视图定义或派生表的情况下,没有TOP和ORDER BY子句)。

答案 2 :(得分:22)

  

...允许在视图定义中使用ORDER BY。

这不是个好主意。视图永远不应该定义ORDER BY。

ORDER BY对性能产生影响 - 使用视图意味着ORDER BY将在解释计划中出现。如果您有一个查询,其中视图连接到立即查询中的任何内容,或者在内联视图中引用(CTE /子查询因子分析) - ORDER BY始终在最终ORDER BY之前运行(假设已定义)。当查询未使用TOP(或LIMIT for MySQL / Postgres)时,排序不是最终结果集的行没有任何好处。

考虑:

CREATE VIEW my_view AS
    SELECT i.item_id,
           i.item_description,
           it.item_type_description
      FROM ITEMS i
      JOIN ITEM_TYPES it ON it.item_type_id = i.item_type_id
  ORDER BY i.item_description

...

  SELECT t.item_id,
         t.item_description,
         t.item_type_description
    FROM my_view t
ORDER BY t.item_type_description

......相当于使用:

  SELECT t.item_id,
         t.item_description,
         t.item_type_description
    FROM (SELECT i.item_id,
                 i.item_description,
                 it.item_type_description
            FROM ITEMS i
            JOIN ITEM_TYPES it ON it.item_type_id = i.item_type_id
        ORDER BY i.item_description) t
ORDER BY t.item_type_description

这很糟糕,因为:

  1. 示例是最初按项目描述排序列表,然后根据项目类型描述对其进行重新排序。这是第一种浪费的资源 - 运行意味着它正在运行:ORDER BY item_type_description, item_description
  2. 由于封装,视图的排序并不明显。这并不意味着您应该使用不同的排序顺序创建多个视图...

答案 3 :(得分:5)

如果没有ORDER BY子句,则TOP 100 PERCENT是多余的。 (正如你所提到的,这是观点的'技巧')

[希望优化器能够优化它。]

答案 4 :(得分:4)

我猜是没有理由而是漠不关心。

此类查询字符串通常由图形查询工具生成。用户加入几个表,添加过滤器,排序顺序并测试结果。由于用户可能希望将查询保存为视图,因此该工具会增加TOP 100 PERCENT。但是,在这种情况下,用户将SQL复制到他的代码中,参数化WHERE子句,并隐藏数据访问层中的所有内容。不在乎,看不见。

答案 5 :(得分:4)

  

我见过其他继承的代码,它使用SELECT TOP 100 PERCENT

原因很简单:企业管理器曾经试图提供帮助并格式化您的代码以便为您提供此代码。没有必要尝试删除它,因为它没有真正伤害任何东西,下次你去改变它EM会再次插入它。

答案 6 :(得分:1)

请尝试下面的内容,希望它能为您效劳。

      SELECT TOP
              ( SELECT COUNT(foo) 
                  From MyTable 
                 WHERE ISNUMERIC (foo) = 1) * 
                  FROM bar WITH(NOLOCK) 
              ORDER BY foo
                 WHERE CAST(foo AS int) > 100
               )

答案 7 :(得分:0)

我认为您可以在结果中使用变量,但除了在视图中获取ORDER BY片段之外,您不会通过隐式声明“TOP 100 PERCENT”来看到好处:

declare @t int
set @t=100
select top (@t) percent * from tableOf

答案 8 :(得分:0)

试试这个,它本身解释了它。除非......

,否则无法使用ORDER BY创建视图
CREATE VIEW v_Test
         AS
           SELECT name
             FROM sysobjects
         ORDER BY name
        GO
  

消息1033,级别15,状态1,过程TestView,第5行ORDER BY   子句在视图,内联函数,派生表中无效,   子查询和公用表表达式,除非TOP,OFFSET或FOR   还指定了XML。

答案 9 :(得分:0)

错误说明了一切...

  

消息1033,级别15,状态1,过程TestView,第5行The ORDER BY   子句在视图,内联函数,派生表,   子查询和公用表表达式,除非是TOP,OFFSET或FOR   还指定了XML。

不要使用TOP 100 PERCENT,请使用TOP n,其中N是数字

SQL Server VIEW(2012年后的版本)忽略了TOP 100 PERCENT(出于我不知道的原因),但我认为MS出于语法原因保留了它。 TOP n更好,可以在视图内工作,并在最初使用视图时以所需的方式对其进行排序,但应为careful