Select Top 100 Percentを使用する理由


82

SQL Server 2005より前は、SQL Serverを「だまして」TOP 100 PERCENTSELECT句に含めることで、ビュー定義でのorderbyの使用を許可できることを理解しています。しかし、SELECT TOP 100 PERCENT動的SQLステートメント内で...を使用する(ASP.NETアプリなどのADOで 使用される)継承した他のコードを見てきました。これには何か理由がありますか?結果は?を含まないのと同じではありませんか?TOP 100 PERCENT


5
「SELECTTOP {0} PERCENT ...」
Michael Petrotta

あなたの最初の文は私の隠された質問の答えの1つになりました。
ムハンマドアシクザマン

私はトップ99.9999999PERCENTを使用し、それは常に機能します。十分に近いです。予想されるレコード数に基づいて、「9」の数を追加する傾向があります。より多くのレコード、より多くの9、そしてそれは常に機能します。私は
SQL2008からSQL2017

回答:


51

中間実体化(グーグル検索)」に使用されました

良い記事:Adam Machanic:中間的な具体化の秘密を探る

彼はMSConnectを調達しので、よりクリーンな方法で実行できます。

私の見解は「本質的に悪いわけではない」ですが、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

これはSQLServer2005でも機能することに注意してください

SELECT TOP 2000000000 ... ORDER BY...

2番目のクエリが失敗するのはなぜですか?内部クエリは(必然的に)完全に評価されていないので?
Kenny Evitt 2013

その2番目のリンクは、一時テーブルを作成するとパフォーマンスが劇的に向上することがある理由を説明しています。
ケニーエビット2013

41

TOP(100)PERCENTは、SQL Serverの最近のバージョンでは完全に無意味であり、(ビュー定義または派生テーブルの場合は対応するORDER BYとともに)クエリプロセッサによって無視されます。

昔々、それはトリックとして使用される可能性がありましたが、それでも信頼性がありませんでした。悲しいことに、Microsoftのグラフィカルツールの中には、この無意味な句をに入れているものがあります。

これが動的SQLに表示される理由については、私にはわかりません。理由がないことは正しいです。結果は、それがなくても同じです(また、ビュー定義または派生テーブルの場合、TOP句とORDER BY句の両方がありません)。


これは真実ではありません。詳細については、@ gbnによる回答のこのリンクを参照してください。
ケニーエビット2013

3
参照しているリンクは、SELECT TOP(100)PERCENT .. ORDER BYについては何も述べていませんが、これは意味がありません。リンクには、SELECT TOP(2147483647).. ORDERBYの使用について記載されています。現在、SQL Serverオプティマイザーは、意味がないため、SELECT TOP(100)PERCENT .. ORDERBYを削除します。この組み合わせは、TOP / ORDERBYなしのSELECTと同じ行のコレクションを常に定義します。オプティマイザは現在、2147483647がすべての行で構成されているかどうかを判断しようとしないため、この場合、TOP-ORDERBYの組み合わせを排除しません。
Steve Kass 2013

2
リンクには実際に次のように記載TOP (100) PERCENTされています。良い考えです。オプティマイザはそのような試みを無視するようになりました。」それは実際にあなたをバックアップします。
ケニーエビット2013

可能であれば、反対票を取り消します。[あなたがあなたの答えを編集するなら、私はそれを
賛成し

1
私が考えを変えたので、あなたはおそらく混乱しています。私の最初のコメントは間違っていました。あなたが正しい。
ケニーエビット2013

23

...ビュー定義でのORDERBYの使用を許可します。

それは良い考えではありません。ビューにORDERBYを定義してはなりません。

ORDER BYはパフォーマンスに影響を与えます。ビューを使用すると、ORDERBYがExplainプランに表示されます。ビューが即時クエリ内の何かに結合されているクエリ、またはインラインビューで参照されているクエリがある場合(CTE /サブクエリファクタリング)-ORDER BYは常に、最後のORDER BYの前に実行されます(定義されていると仮定)。クエリがTOP(またはMySQL / Postgresの場合はLIMIT)を使用していない場合、最終結果セットではない行を並べ替えるメリットはありません。

考えてみましょう:

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. カプセル化のため、ビューが何によって順序付けられているかは明らかではありません。これは、異なる並べ替え順序で複数のビューを作成する必要があるという意味ではありません...

6

ORDER BY句がない場合TOP 100 PERCENTは、冗長です。(あなたが言うように、これはビューのある「トリック」でした)

[うまくいけば、オプティマイザーはこれを最適化するでしょう。]


5

SELECT TOP 100PERCENTを使用する継承した他のコードを見ました

この理由は単純です。EnterpriseManagerは、これを含めるために役立つようにコードをフォーマットするために使用されていました。それは実際には何も傷つけなかったので、それを削除しようとしても意味がありませんでした。次にそれを変更しようとすると、EMが再び挿入します。


4

理由はないが無関心だと思う。

このようなクエリ文字列は通常、グラフィカルクエリツールによって生成されます。ユーザーはいくつかのテーブルを結合し、フィルターと並べ替え順序を追加して、結果をテストします。ユーザーはクエリをビューとして保存したい場合があるため、ツールはTOP 100PERCENTを追加します。ただし、この場合、ユーザーはSQLを自分のコードにコピーし、WHERE句をパラメーター化して、データアクセス層内のすべてを非表示にします。心の外、見えない。


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
               )

1

エラーはそれをすべて言います...

メッセージ1033、レベル15、状態1、プロシージャTestView、5行目ORDER BY句は、TOP、OFFSET、またはFOR XMLも指定されていない限り、ビュー、インライン関数、派生テーブル、サブクエリ、および共通テーブル式では無効です。

使用しないTOP 100 PERCENT、使用するTOP n、ここでNは数値です

TOP 100 PERCENT(私が知らない理由で)はSQL Server VIEW(2012年以降のバージョン)では無視されますが、MSは構文上の理由でそれを保持したと思います。TOP nの方が優れており、ビュー内で機能し、ビューを最初に使用するときに希望どおりに並べ替えますが、注意してください


0

結果で変数を使用できると思いますが、ビューにORDER BYピースを表示する以外に、「TOP100PERCENT」と暗黙的に指定してもメリットはありません。

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

2
問題はWhy use Select Top 100 Percent、パーセントの変数カウントを取得することではありません。
bummi 2014年

0

これを試してみてください、それはそれ自体をほとんど説明しています。次の場合を除いて、ORDERBYを使用してビューを作成することはできません...

CREATE VIEW v_Test
         AS
           SELECT name
             FROM sysobjects
         ORDER BY name
        GO

メッセージ1033、レベル15、状態1、プロシージャTestView、5行目ORDER BY句は、TOP、OFFSET、またはFOR XMLも指定されていない限り、ビュー、インライン関数、派生テーブル、サブクエリ、および共通テーブル式では無効です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.