web-dev-qa-db-ja.com

合計時間の75%を使用するクエリ「Creating Sort Index」のMySQLプロファイル

クエリを最適化する方法を理解しようとしています(約100msかかります)。実行中のプロファイルCreating Sort Indexを使用して75%の合計時間。まず、ソートインデックスの作成に正確に影響するものは何ですか。 disk/ioですか?

次に、クエリ自体に行うことができる最適化はありますか?

SELECT r.`id`, 
       r.name, 
       r.public_uri, 
       rv.version, 
       rv.interpreter, 
       rv.notes, 
       rv.content, 
       r.added, 
       r.added_by, 
       r.modified, 
       r.modified_by, 
       r.public, 
       r.public_by
  FROM recipe_heads rh, 
       recipes r, 
       recipe_versions rv
 WHERE rh.recipe = r.`id` 
   AND rh.recipe_version = rv.`id` 
   AND r.`id` = rv.recipe
ORDER BY r.added DESC

説明: Screenshot

10
Justin

巨大なクエリについても同様の問題がありました。多くの場合、クエリは、4億行のDBの負荷に応じて、数時間(最大7〜8)実行されました。ただし、私たちの目標は、select col1、col2、col3、count(1)、count(distinct col4)などのグループ結果をテーブルグループから1,2,3で達成することでした。

根本的な問題はあなたの問題と同じですが、どちらの場合もDBは結果を内部的にソート(順序付け)します。

  • ソートインデックスの作成方法。 mysqlのWebサイトでは、「スレッドは内部一時テーブルを使用して解決されるSELECTを処理しています」と述べています。私のアルゴリズムの理解によれば、システムはおそらくデータをチャンクに分割し、ディスクからこのチャンクを1つずつ読み取り、個々のチャンクを並べ替え、一時的なディスク領域に戻すなどです。システムはすべてのチャンクに対してこれを行い、最終的にマージソートを実行します。これには、広範な読み取り/書き込みが含まれます。

考えられる解決策は、DBのメモリを増やす(メモリに留まることができるより大きなチャンクを作成できるようにする)か、どこかに大きなメモリがある場合は、DBからストリーミングすることによってソリューションをプログラムすることです。これはnlogn時間で達成できます。

プログラム的には、平均2時間から一貫して7.5分に時間を短縮できました。

6
Chandni

「ソートインデックスの作成」は、「order by」句に基づいて戻り値の順序を決定するデータベースです。ここでの主な制限は、使用可能なCPU/CPU速度、およびメモリ帯域幅です。少なくともこの小さなクエリでは、データがすべてメモリに格納されるまで、並べ替えは行われません。クエリをプロファイリングした場合、リソースの待機が表示されますか?

このクエリを高速化するには、「r.added」にインデックスを追加することを検討してください。説明によると、インデックスが存在しないようです。

4
Unicorno Marley