2

妥当な時間内に 2M 行のテーブルから上位 100 行を取得するのに問題があります。問題はパーツごとの順序です。このクエリの結果を取得するのに 50 分以上かかります。この問題の最善の解決策は何ですか?

select top 100 * from THETABLE TT
Inner join SecondTable ST on TT.TypeID = ST.TypeID
ORDER BY DATEDIFF(Day, TT.LastCheckDate, GETDATE()) * ST.SomeParam DESC

どうもありがとう、

ベンツィー

編集: * TheTable は 2M 行のテーブルです。* SomeParam には 15 個の異なる値があります (多かれ少なかれ)

4

5 に答える 5

0

行数を減らすにSecondTableは、LastCheckDate で並べ替えられた各レコードの上位 (100) を取得し、それらをすべて結合して、最終的に上位 (100) を選択します。これには、一時テーブルまたは動的 SQL 生成クエリを使用します。

このソリューションでは、カーソルを使用して、SecondTable の各値の上位 100 レコードをフェッチします。TheTable の (TypeID, LastCheckDate) のインデックスを使用すると、即座に実行されます (私のシステムでは、700,000 レコードと 50 の SecondTable エントリのテーブルでテストされています)。

declare @SomeParam varchar(3)
declare @TypeID int

declare @tbl table (TheTableID int, LastCheckDate datetime, SomeParam float)

declare rstX cursor local fast_forward for
      select TypeID, SomeParam
        from SecondTable

open rstX
while 1 = 1
begin
    fetch next from rstX into @TypeID, @SomeParam
    if @@fetch_status <> 0
       break
    insert into @tbl
    select top 100 ID, LastCheckDate, @SomeParam
      from TheTable
     where TypeID = @TypeID
     order by LastCheckDate
end
close rstX
deallocate rstX

select top 100 *
from @tbl
order by DATEDIFF(Day, LastCheckDate, GETDATE()) * SomeParam

明らかに、このソリューションは ID のみをフェッチします。列を追加して一時テーブルを拡張することができます。

于 2012-07-26T15:06:04.043 に答える
0

DATEDIFF(Day, TT.LastCheckDate, GETDATE())「最後のチェック」からの日数です。

注文するだけでTT.LastCheckDate、同様の注文が得られます。

編集 おそらく、戻ってくるとは思わない日付を見つけ出し、それらをフィルタリングすることができます。もちろん、その LastDateCheck 列にもインデックスが必要です。すべてがうまくいけば、チェックするレコードのリストを少なくとも 2M から管理可能な量に短縮できます。

于 2012-07-26T14:22:25.447 に答える
0

このフェッチを高速化するには、次の 2 つの点に注意してください。

  1. このクエリを頻繁に実行する必要がある場合は、列「lastCheckDate」にインデックスを付ける必要があります。使用しているSQLデータベースに関係なく、列に適切に定義されたインデックスにより、特にorders by句での選択が高速になります。

  2. 選択クエリを実行する前に日付計算を実行します。行のcheckDateと現在の日付の日数の差を、いくつかのパラメータに掛けています。乗算は行の順序に影響しますか? これは単に「lastCheckDate desc」で注文できますか? 同じ結果を返す他の並べ替えオプションを調べます。

于 2012-07-26T14:25:07.447 に答える