3

ネットを荒らした多くの議論が私の問題の側面をカバーしていますが、ここに当てはまるパターンは見当たりません:

MySQL で EF 3.5 を使用する基本的な .NET WinForm アプリケーションがあります。アプリケーションはほとんどのクエリで正常に動作しますが、Distinct() を含むクエリは非常に遅くなるか、「操作が完了する前にタイムアウト期間が経過したか、サーバーが応答していません」というエラーが発生します。マシンの再起動後に最初に実行されたときに例外が発生します。つまり、アプリケーションを再起動すると、MySQL サービスを停止して再起動した後でも、Distinct() クエリは正常に機能します (つまり、1 秒もかかりません)。

アプリケーションを再実行したり、MySQL を再起動したりしても問題を再現できないという事実は、EF コンパイルまたは MySQL キャッシングが要因であることを除外します。再起動後にのみ、問題が再発します。おそらく.NETの初期化の問題か、OSに関連する何かだと思います。この問題は、XP および Win 7 で確認されています。

どんなアイデアでも大歓迎です。(マシンを再起動せずに問題を再現しようとするアイデアもあり、これは非常に非現実的です:-)

アップデート:

EF によって生成されるクエリは次のようになります。

SELECT Distinct1.C2 FROM (
    SELECT DISTINCT YEAR(Extent1.RecDate) AS C2 
    FROM dailyrecord AS Extent1
    WHERE (Extent1.STN = 430030) AND (Extent1.WBAN = 99999)
) AS Distinct1;

これを mysql シェルで実行すると、最初は約 30 秒かかり、その後は mysql を再起動した後でも約 1 秒かかります。再起動後、30 秒に戻ります。OS は最初は db ファイル全体を読み取っているように見えますが、その後はそうではありません (変更されたクエリ パラメータを使用しても、後続のクエリでの HD アクティビティはほとんどありません)。

OS の読み取りキャッシュをフラッシュして自分の理論をテストするにはどうすればよいですか?

4

1 に答える 1

1

かなりのテストの後、これが明らかになりました:

  • 上記の「DISTINCT」クエリのように、「WHERE」句に主キーの一部が含まれている場合、多くのクエリはデータ ファイル全体を読み取る必要があるため、MySQL およびおそらく任意の DBMS で定義上非常に低速です。 、ただし主キー全体ではありません (この場合は 4 つのフィールドの複合体でした)。

  • 遅いクエリが頻繁に発生し、アプリケーションで煩わしい場合は、検索基準 ("WHERE" フィールド) にインデックスを追加する必要があります。これにより、クエリが大幅に高速化されます (最終的に最初に投稿された問題の解決策になりました)。ただし、ディスク上のデータ (.MYI ファイル) のサイズが増加しますが、.MYD ファイルのサイズはわずかに減少しますが、全体的には増加します。合計データサイズ。インデックスを追加すると、インデックスも更新する必要があるため、INSERT、UPDATE、および DELETE クエリの時間が長くなる可能性があります。 挿入はほとんどの場合、1 つずつ実行されるため、パフォーマンスの低下はほとんど目立ちません。一括 DELETE クエリとは異なります (以下を参照してください)。

  • クエリの非効率性は、OS (私の場合は MS Windows XP) によって隠されています。レコードごとにテーブル全体を読み取る必要があるクエリは、最初に遭遇したときは非常に遅くなります。ただし、OS はファイルをキャッシュし、クエリ自体が変更されたとしても、パラメーターが変更された場合でも、後続のクエリははるかに高速になります。テーブル ファイル全体の読み取りを必要とする非効率的なクエリは、OS によってキャッシュされるとすぐに表示されます。これにより、テストの間に OS を再起動する必要があるため、クエリの調整が難しくなります。ネットをトローリングした後、Windows で読み取りキャッシュをフラッシュする実用的な方法をまだ見つけていません。

  • 関連する非効率的なクエリは、DELETE FROM myTable WHERE field1 = value です。フィールド 1 にインデックスがある場合でも、削除するレコードが多数ある場合 (私の場合は 10,000 レコードで 30 秒) (これらの例ではすべて MySQL、ストレージ エンジン MYISAM を使用)、これは遅くなります。これは、DBMS がテーブル ファイル全体をディスクから (ディスクに) 読み取る (場合によっては書き込む) 必要があるためです (DELETE が物理的にどのように実行されるかによって異なります)。繰り返しますが、これは OS によってマスクされます。最初は遅いですが、その後のクエリでは非常に高速です (私の XP マシンでは 30 倍高速です)。 . 上記のようにインデックスを追加すると、削除クエリにかかる時間が長くなる場合があります。

ご意見やご感想をお待ちしております。

于 2012-11-30T12:55:34.920 に答える