24

クエリは次のとおりです (最大のテーブルには約 40,000 行あります)

SELECT
  Course.CourseID,
  Course.Description,
  UserCourse.UserID,
  UserCourse.TimeAllowed,
  UserCourse.CreatedOn,
  UserCourse.PassedOn,
  UserCourse.IssuedOn,
  C.LessonCnt
FROM
  UserCourse
INNER JOIN
  Course
USING(CourseID)
INNER JOIN
(
  SELECT CourseID, COUNT(*) AS LessonCnt FROM CourseSection GROUP BY CourseID
) C
USING(CourseID)
WHERE 
  UserCourse.UserID = 8810

これを実行すると、非常に高速に実行されます (およそ 0.05 秒)。13 行を返します。

クエリの最後に句を追加するとORDER BY(任意の列で並べ替える)、クエリに約 10 秒かかります。

現在、このデータベースを本番環境で使用していますが、すべて正常に動作しています。私の他のすべてのクエリは迅速です。

それが何であるかについてのアイデアはありますか?MySQL のクエリ ブラウザで、コマンド ラインからクエリを実行しました。両方の場所で、ORDER BY.

編集: Tolgahan ALBAYRAK ソリューションは機能しますが、なぜ機能するのか説明できますか?

4

7 に答える 7

18

たぶんこれが役立ちます:

SELECT * FROM (    
     SELECT
      Course.CourseID,
      Course.Description,
      UserCourse.UserID,
      UserCourse.TimeAllowed,
      UserCourse.CreatedOn,
      UserCourse.PassedOn,
      UserCourse.IssuedOn,
      C.LessonCnt
    FROM
      UserCourse
    INNER JOIN
      Course
    USING(CourseID)
    INNER JOIN
    (
      SELECT CourseID, COUNT(*) AS LessonCnt FROM CourseSection GROUP BY CourseID
    ) C
    USING(CourseID)
    WHERE 
      UserCourse.UserID = 8810
) ORDER BY CourseID
于 2009-05-19T19:45:50.880 に答える
7

並べ替えている列はインデックス付けされていますか?

インデックスを作成すると、順序付けとフィルタリングが大幅に高速化されます。

于 2009-05-19T19:45:05.377 に答える
3

「 UserCourse 」から選択しています。これは、コースとユーザーの間の結合テーブルであると想定しています(多対多)。「UserCourse」テーブルで、並べ替える必要がある列にインデックスを付ける必要があります。

CourseIDで並べ替える」場合、 UserCourseテーブルでインデックスを作成する必要があります。

結合テーブル (つまり UserCourse) に存在しないその他の列による順序付けは、速度を最適化するために、結合テーブルでさらに非正規化とインデックス作成が必要になる場合があります。つまり、結合テーブルにその列のコピーがあり、それにインデックスを付ける必要があります。

PS Tolgahan Albayrak の回答は、この質問に対しては正しいですが、「LIMIT x」クエリを実行している場合、望ましい結果が得られません。

于 2016-02-22T10:46:20.160 に答える
1

答えが遅すぎることに気付きますが、同様の問題が発生しました。クエリ時間を数秒から 5 分に増やして順序を追加し、それを高速化するための他のほとんどの提案を試してみたところ、/tmp ファイルが 12G になることに気付きました。このクエリ。返される varchar(20000) フィールドが「trim(」されるようにクエリを変更し、パフォーマンスが劇的に改善されました (数秒に戻りました)。したがって、クエリの一部として大きな varchar を返しているかどうかを確認する価値があると思います。それらを処理します (おそらく substring(x, 1, length(x))?? それらをトリミングしたくない場合。クエリは 500k 行を返し、/tmp ファイルは各行が約 20k のデータを使用していることを示しました。

于 2012-08-17T12:03:14.293 に答える
1

データベースの統計を更新しましたか? 私は似たようなものに遭遇しました.2つの同一のクエリがあり、唯一の違いは大文字で、1つは1/2秒で返され、もう1つは5分近くかかりました。統計を更新すると問題が解決しました

于 2009-05-19T19:47:24.137 に答える
0

同様の質問が以前ここで尋ねられました。

それはあなたにも役立つかもしれません。基本的に、複合インデックスの使用と順序による仕組みについて説明します。

于 2009-05-19T19:57:16.363 に答える
0

今日、私は同じ種類の問題に遭遇していました。結合されたテーブルのフィールドで結果セットを並べ替えるとすぐに、クエリ全体が恐ろしく遅くなり、100 秒以上かかりました。

サーバーは MySQL 5.0.51a を実行していましたが、同じクエリが、MySQL 5.1 を使用するサーバーで常に実行されるはずの速度で実行されていることに偶然気付きました。そのクエリの説明を比較すると、明らかにインデックスの使用法と処理が大幅に変更されていることがわかりました (少なくとも 5.0 -> 5.1 から)。

したがって、このような問題に遭遇した場合、おそらく解決策は、MySQL をアップグレードすることです。

于 2011-09-29T14:29:01.113 に答える