2011-07-14 3 views
4

私のアプリケーションはC#[.NET 3.5]およびMySQL 5.1バックエンドにあります。ユーザの種類に合わせてレコードフィルタリングを高速化する

私はTextBoxとDataGridViewを持つWindowsフォームを持っています。ユーザーがTextBoxに少数の文字を入力すると、Like節を含むSQLクエリが実行され、下のDataGridViewに表示されているレコードがフィルタ処理されます。

アイテムリストがかなり大きくなりました。また、適切な文字入力ごとにSQLクエリを実行していません。別の方法として、アプリケーションが読み込まれたときにDataSetを作成し、最近の株式ポジションを先に入力する方法があります。 LINQなどを使用してメモリ内のレコードセットをフィルタリングするよりも、しかし、この方法も最適化されていません。なぜなら、新しい請求書が作成されるたびに在庫からのアイテムが減り、インメモリレコードセットを更新する必要があるたびにです。

他の最適化された高速の方法はありますか?

+0

これが.NET 4の場合、私はリアクティブエクステンション(Rx)を提案します。これは入門ハンズオンラボの例の1つです。しかし、v4より前のv4がどの程度うまくサポートされているかはわかりません。 – Richard

+1

私が提案できるのは、分を使用することです。検索クエリが実行される前の長さ。たとえば、検索語が3文字以上のときにのみクエリを実行します。 –

答えて

5

デシベル側

上のすべてを最適化する方法に

データベース層
Great postを行うことができますいくつかの最適化は、あなたはまた、シャーディングと水平スケーリング

アプリケーションを試すことができますがあります側面
データセットは重く、かさばり、遅く、メインタイにするのが難しいため、使用しないでくださいnはdbと同じデータのコピーです。

  • バックグラウンドスレッドで
  • 実行検索を入力
  • のみ後に2つのまたは3つのシンボルを検索

    • キャッシュユーザ検索
    • スタート20(または何でも)を先頭に絞って検索:いくつかのトリック上だと思います検索がさまざまなコード抽象化から軽いものであることを確認して、簡単にしてください
    • 検索クエリを最適化すると、SQL操作の順序が問題になります

    インフラ

    • 、それを改善するためにあらゆる可能性をあなたの接続速度をチェック!
    • がJaCraigが言っていることの可能
    0

    MSILのコーディングを見ることをお勧めします。私たちはメモリ内のレコードをすばやく更新する必要がある同様のシナリオを持っていました。標準的な.NETの方法を使用するのは遅すぎたので、私たちは根本的なMSILで遊んでメモリに直接書きました。これは危険ですが、正しく実行されると、管理されていないメモリを使用して利益を得ることができます。

    Increasing Application Performance

    0

    先読み問題を解決するために「正しい」方法は、「トライ」や「基数木」です。必要な場合はこれをSQLで実装できますが、それは作業の場です。また、データセットが動的に変化するケースにどのように適応するのが簡単かはわかりません。

    「比較的小さい」データセット(環境によっては10 KBのアイテムが最大)の場合、トライはRAMに保存できます。

    +0

    正しい方法は、あなたが記述しているデータ構造を実装するものを実際に使用することです。そうする必要はありません:) SOLRとLuceneはそのような技術です。 –

    0

    like節でどの程度の柔軟性が許されているのかよく分かりませんが、新しいデータグリッド表示が現在のもののサブセットになる場合は、ユーザーがテキストボックスに入力するタイミングを教えてください通常、より多くの文字が検索をより具体的にしているためです。

    したがって、新しいデータが既存のデータのサブセットでない場合にのみデータベースにクエリを作成し、それをデータセットに保存することができます。新しいデータがサブセットになるときは、データセットのフィルタを更新します。

    データを最新の状態に保つ限り(在庫が変更されている商品のことを意味する場合)、妥当な間隔で再クエリするタイマーを使用することもできます。テキストボックスに入力するとタイマーをリセットすることができます。タイマーによってタイマーが発生すると同時に、データベースクエリーが発生します。

    2

    私は何か類似していましたが、あなたの正確な要件に応じて、それは役に立たないかもしれません。私たちがやったことは、実際にはアプリケーションを取り出し、データベースからいくつかのRESTサービスにクエリを分けることでした。サーバーのバックエンド部分では、アプリケーションがすべてをメモリに移動し、起動時にキャッシュします。すべての変更をサーバー経由で送信して、キャッシュの一部を無効にし、必要に応じて再ロードすることができました。

    クライアント側では、いくつかの文字が入力されると、サーバーに要求を送信しました。サーバーは、それに一致する項目のリストを返送し、クライアント側にキャッシュしました。次に、そのリストのクライアント側をフィルタリングし、フィールドがクリアされたとき、または最初のカップルの文字が変更されたときにのみ、別の要求を行いました。

    サーバー部分がなくても、クライアント側と同様のことができます。

    2

    だけ拡張としてアプリケーションの近くにあなたのDBを入れて、私はあなたがWebサービスを作成する必要があると思うが、コードのこの部分の周りに境界線を引くことになりませんそれが複雑になるので意味があります。

    また、私はデータベース全体をキャッシュしないでしょう。正確な量を見つけるためにいくつかのチューニングとテストを行うことができますが、最大2文字または3文字の深さに応じて、大文字と小文字を区別しない場合は10個のアイテムがメモリ内に170kアイテムあります。

    各文字の追加にハッシュセットを使用して10個のアイテムを返し、次に開始する最初の3文字を超えるときデータベースに問い合わせる。

    ここでJaCraigがヒットしたキーは、キャッシュを清潔に保つために、この同じコードスペースを通過するための更新や修正が必要だということです。 SOLRを使用してデータベースを検索インデックスをオフに構築するに

    public Items[] GetItems(string searchString) 
    { 
        if (searchString.Length < 4) 
        { 
        return _cacheDataProvider.GetItems(searchString); 
        } 
    
        return _mySqlDataProvider.GetItems(searchString); 
    } 
    
    public void UpdateItem(Item itemToBeUpdated) 
    { 
        _cacheDataProvider.UpdateItem(itemToBeUpdated); 
        _mySqlDataProvider.UpdateItem(itemToBeUpdated); 
    } 
    
    1

    ルック:http://lucene.apache.org/solr/ をとのそれを照会あなたがDALを持っている場合

    合理的に、これはただのような何かをやって別々のデータプロバイダとしてそこの下で暮らすことができWebサービスのエンドポイントを選択します。

    ユーザーが入力をやめた後でクエリを送信するだけでも、多くのことに役立ちます。次のクエリを送信する待機時間として約300ミリ秒を使いました。フロントエンド用のプラグインがたくさんありますが、それはあなた自身のために構築したくなければ、同様のルールでエンドポイントに当たってしまいます。