为何使用Select Top 100%?

Ed *_*bor 80 sql t-sql sql-server

据我所知,在SQL Server 2005之前,您可以"欺骗"SQL Server以允许在视图定义中使用顺序,也包括TOP 100 PERCENTSELECT子句中.但是我已经看到了我继承的其他代码,它们SELECT TOP 100 PERCENT在动态SQL语句中使用...(在 ASP.NET应用程序中用于ADO等).这有什么理由吗?结果不一样,包括?TOP 100 PERCENT

gbn*_*gbn 51

它被用于" 中间物化(谷歌搜索) "

好文章:Adam Machanic:探索中间物化的秘密

他甚至提出了MS Connect,因此可以更清洁的方式完成

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

工作的例子

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

SELECT foo From MyTable WHERE ISNUMERIC (foo) = 1 AND CAST(foo AS int) > 100
Run Code Online (Sandbox Code Playgroud)

这可能也会失败,因为

SELECT foo
FROM
    (SELECT foo From MyTable WHERE ISNUMERIC (foo) = 1) bar
WHERE
    CAST(foo AS int) > 100
Run Code Online (Sandbox Code Playgroud)

但是,这在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
Run Code Online (Sandbox Code Playgroud)

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

SELECT TOP 2000000000 ... ORDER BY...
Run Code Online (Sandbox Code Playgroud)


Ste*_*ass 39

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

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

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

  • 您引用的链接没有说明SELECT TOP(100)PERCENT .. ORDER BY,这是没有意义的.该链接提到了使用SELECT TOP(2147483647).. ORDER BY.目前,SQL Server优化器将消除SELECT TOP(100)PERCENT .. ORDER BY,因为它没有意义.该组合始终定义与没有TOP/ORDER BY的SELECT相同的行集合.优化器当前不会尝试确定2147483647是否包含所有行,因此在这种情况下它不会消除TOP-ORDER BY组合. (3认同)
  • 该链接实际上提到了`TOP(100)PERCENT`:"...我可能尝试强制派生表的中间实现,没有临时表,通过使用TOP 100 PERCENT和ORDER BY.不幸的是,SQL Server查询优化器团队认为这不是一个好主意,优化器现在忽略了这种尝试." 它实际上支持你. (2认同)
  • 你可能很困惑,因为我改变了主意;我的第一条评论是错误的;你说得对。 (2认同)

OMG*_*ies 23

...允许在视图定义中使用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
Run Code Online (Sandbox Code Playgroud)

...

  SELECT t.item_id,
         t.item_description,
         t.item_type_description
    FROM my_view t
ORDER BY t.item_type_description
Run Code Online (Sandbox Code Playgroud)

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

  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
Run Code Online (Sandbox Code Playgroud)

这很糟糕,因为:

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


Mit*_*eat 6

如果没有ORDER BY条款,那么TOP 100 PERCENT就是多余的.(正如你所提到的,这是观看的'技巧')

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


Pet*_*hia 5

我想,除了冷漠之外,没有任何原因。

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


Joe*_*orn 5

我看到了我继承的其他代码,这些代码使用SELECT TOP 100 PERCENT

原因很简单:企业管理器曾经试图提供帮助,并格式化您的代码以为您提供帮助。尝试删除它毫无意义,因为它并没有真正伤害到任何东西,下次您进行更改时,EM会再次插入它。