2012-04-30 6 views
2

私は簡単なクエリを実行したい単純なデータベースを持っています。実行に時間がかかるSQLクエリの最適化

これらは、私のデータベーステーブルの列です:

  • は、タイムスタンプ
  • をexternal_id検証
  • 理由データム
  • UUR
  • のAf

ronden列は次のとおりです。

  • external_id一定メートル
  • TimestampのIDが何も
  • Valueは、そのメーターの値が
  • Validationがちょうどyesまたはnoではありませんんです
  • Reasonちょうどvarchar va理由
  • DatumとLUEは
  • Afronden

私は最高のを取得することを目標となった実行したいクエリを丸めるために必要なカラムがあることをその時の日付

  • Uurされています各日の値の合計の最低値。

    あなたが見ているように、毎日が数時間で分けられているか、チェックしなければならないか、データムは同じか変更され、その合計値が得られます。

    これが私のクエリです:唯一の44000行が処理された22分後にした後

    Declare @totaal bigInt 
    Declare @tussentotaal bigint 
    Declare @Datum varchar 
    Declare @datumverschil varchar 
    Declare @hoogste bigint 
    Declare @laagste bigint 
    Declare @teller bigint 
    Declare @tellettotaal bigint 
    
    set @tellettotaal = (select count(*) from cresent_opdracht_de_proost_wim.dbo.[test]) 
    
    Set @teller = 1 
    
    SET @datum = (Select top(1) datum 
           from cresent_opdracht_de_proost_wim.dbo.[test] 
           order by afronden asc) 
    
    Set @datumverschil = @Datum 
    set @tussentotaal = 0 
    set @totaal = 0 
    set @hoogste = 1775000006856 
    set @laagste = 1775000006856 
    
    while @teller <= @tellettotaal 
    begin 
        if @teller = 1 
        Begin 
        set @tussentotaal = (select top(1) value 
             from cresent_opdracht_de_proost_wim.dbo.[test] 
             order by afronden asc) 
    
        if @tussentotaal != 0 
        begin 
         Set @tussentotaal = @tussentotaal/100 
        end 
        End 
        Else 
        begin 
        SET @tussentotaal = (Select top(1) value 
             from (select top (@teller) * 
               from cresent_opdracht_de_proost_wim.dbo.[test]) q 
             order by afronden desc) 
    
        Set @tussentotaal = @tussentotaal/100 
        end 
    
        if @tussentotaal != 0 
        Begin 
        Set @totaal = @totaal + @tussentotaal 
        end 
    
        SET @teller= @teller + 1 
    
        Set @datumverschil = (Select top(1) datum 
             from (select top (@teller) * 
               from cresent_opdracht_de_proost_wim.dbo.[test]) q 
             order by afronden desc) 
    
        if @datum != @datumverschil 
        Begin 
        if @totaal >= @hoogste 
        begin 
         set @hoogste = @totaal 
        end 
    
        if @totaal <= @laagste 
        begin 
         if @totaal != 0 
         Begin 
         set @laagste = @totaal 
         end 
        end 
    
        Set @datum = @datumverschil 
        set @totaal = 0 
        select @teller As teller 
        end 
    end 
    
    Select @hoogste As hoogste 
    Select @laagste As laagste 
    

    クエリを最適化する方法を知っている人はいますか?

  • +0

    そのデータベースとテーブルを作成したMySQLを表示します。特に、あなたが持っているインデックスを表示します。 –

    +2

    RBARコードが何をしているのかを最初に把握する必要がないので、サンプルデータと望ましい結果を掲載する方が良い。答えはおそらくセットベースの方法でそれを書き換えることでしょう。また、どのバージョンのSQL Server? –

    +0

    私は最初に写真を挿入したかったが、私の評判は十分ではなかったので、私はそれらをインターネットにアップロードした。私のデータベースはcsvによってcreadedされ、これはデータベースの外観です。 – Wimdp

    答えて

    1

    本来、壊れた手続き型アプローチを使用しないことが考えられるだろうと考えていましたか?

    まず、ロジックが壊れている可能性があります。時間がかかり過ぎると、デッドループが発生する可能性があります。申し訳ありませんが、ほとんどの人がフリンジランゲージを理解することは非常に難しいです。つまり、英語ではないものなので、テーブルとフィールドの名前は意味をなさないものです。ナンセンスはそれほど知識がない人がデバッグすることはほとんどありません。

    THAT SAID:トップ1を上回る無意味なループを実行しないで、合計でクエリを少なくすることができると思います。残念ながら、ループを取り除き、結果セットをコンパイルするONEステートメントを作成してください。真剣に。それは可能なはずです。クエリーオプティマイザを超越して、20年前にdbase時代に多くの人がしたように、手続き型データベースコードを書き直してはいけません。一般に。クエリは線形であり、並列化がないことを意味し、条件のマイクロ管理はクエリオプティマイザがスマートなものを実行できないことを意味します(最適化はステートメントごとです)。 1つのステートメントに結果セットを定義すると、それがどれほど効率的かを疑問に思うかもしれません。

    私は最後に、あなたが基本的にあなたが質問を書いたよりも優れているものを圧倒しようとしていることが分かります。 SQLを使用 - 結果セットを定義します。

    最後に、データの分布やあまりにも多くのインデックスを知らなくても、私たちは本当に助けてはいけません。おそらくあなたは賢明な指標を見逃しているでしょうか?誰が知っている - あなたは何も言いません(クエリプランの出力なし、テーブル定義なし、インデックス定義なし)。

    データ型を悪用しないでください。Declare @Datum varchar - OUCH。これまでSQL ServerのDATEデータ型について聞いたことがありますか?