sql >> データベース >  >> RDS >> Mysql

MySQLでのクエリパフォーマンスの最適化

    専門家は、パフォーマンス効率の高いクエリを作成する方法を知っています。経験は知恵を熟成させますが、少なくとも最初に理解しなければならないことがいくつかあります。たとえば、クエリ設計の重要な考慮事項を理解する必要があります。クエリが内部でどのように実行されるか、失敗する場所、最適化パターンなど。この記事では、MySQLでクエリを設計する際に熟考するためのいくつかの最適化ポイントを提供します。

    一部のクエリが遅いのはなぜですか?

    SQLクエリの一般的な問題は、実際に必要な数よりも多くのデータが取得されていることです。もちろん、多くのデータをふるいにかけるクエリがあり、それらについては多くのことを行うことはできませんが、一般的ではありません。ほとんどの場合、クエリのパフォーマンスが低下するのはクエリの設計が悪いことです。すべてのクエリ設計の後で、クエリが実行された後に何が起こる可能性があるかなど、いくつかの側面を内省する必要があります。

    1. SQLクエリがアクセスする列または行が多すぎますか?
    2. MySQLサーバーは、目的の結果を取得するために分析する行が多すぎますか?

    MySQLサーバーに大量のデータを分析させるが、ふるいにかけるときにそれらをスローするクエリがあります。これは、ネットワークオーバーヘッド、メモリ消費量の多さ、サーバーのCPUリソース使用量の多さなど、多くの点でサーバーにとって余分な作業です。その結果、パフォーマンスが低下します。

    設計中にあまり役に立たない場合もありますが、注意深く結果を見積もり、内省すれば、悪いクエリは少なくとも良くなるとは言えないまでもうまくいく可能性があります。

    >

    一般的な間違いとその解決策

    クエリの作成中によくある間違いがかなりあります。ここにそれらのいくつかがあります。同じ行でさらにいくつかの考えを見つけることができます。考えられる解決策でクエリのパフォーマンスが低下する理由は次のとおりです。

    行が多すぎます

    多くの場合、データを取得するクエリを記述し、MySQLが結果セット全体を返すために必要な処理量を見落としながら、オンデマンドで結果を提供すると想定するという間違いがあります。実際に最初に表示する必要があるのは10個だけであるのに、eコマースサイトの100個の製品の詳細をフェッチするためにSELECTステートメントが起動されたとします。 MySQLは10行のみをフェッチし、クエリの実行を停止すると思うかもしれません。しかし、違います。 MySQLが行うことは、完全な結果セットを生成し、クライアントにフィードすることです。クライアントライブラリは完全なセットを受け取り、そのほとんどを破棄し、シークしたもののうち10個だけを保持します。これは明らかに多くのリソースを浪費します。

    ただし、このような状況では、クエリでLIMIT句を使用して解決策を提供できます。

    SELECT
          col1, col2,...
    FROM
          table_name
    LIMIT
          [offset,] count; 
    

    LIMIT句は、1つまたは2つのパラメーターを受け入れます。最初のものはオフセットを指定し、2番目のものはカウントを指定します。パラメータが1つだけ指定されている場合は、結果セットの先頭からの行数を示します。

    たとえば、テーブルから10行を選択するには、次のように記述します。

    SELECT
          e.emp_name, e.phone, e.email
    FROM 
          employee e
    LIMIT 10;
    

    そして、11レコードから始めて、次の10行を選択するには、次のように記述できます。

    SELECT
          e.emp_name, e.phone, e.email
    FROM
          employee e
    LIMIT 10, 10;
    

    列が多すぎます

    常にクエリを見てください:疑いを持ってSELECT*。このクエリはすべての列を返し、おそらく一部の列のみが必要です。すべての列を取得することの最大の欠点は、インデックスの使用を妨げることによって最適化を妨げ、サーバーに過剰なI / O、メモリ、およびCPUリソースを要求することです。

    すべての列を取得するこのようなユニバーサルクエリは無駄になる可能性があることを理解してください。開発者が同じコードを複数の場所で使用できるため、便利だという人もいます。関係するコストが考慮の範囲内で制限されている場合は、それで問題ありません。取得したデータをキャッシュすると、このコンテキストで役立つ場合があります。ただし、注意が必要です。パフォーマンスを活用することは洗練された仕事であり、そのような贅沢にはパフォーマンスの場がない可能性があります。

    経験則では、このようなユニバーサルクエリを回避するか、フェッチされる列の数を可能な限り最小限に抑えます。

    データ分析が多すぎます

    クエリは問題のない望ましい結果を返しますが、これらのクエリは、処理中に結果を生成する前に大量のデータを調べる必要があるような方法で記述される場合があります。したがって、MySQLでは、次のコスト指標に従って測定する必要があります。

    • 実行時間
    • 調べた行
    • 調査した列

    これらのメトリックからクエリコストの概算を取得できます。これらは、クエリを処理するためのMySQLによる内部的なデータアクセスの量と、クエリの実行速度を反映しています。これらのメトリックは低速のクエリログに記録されるため、結果を返すにはデータが多すぎるクエリを調査して見つけることをお勧めします。 MySQLデータベースは、指定された実行時間を超えるすべてのクエリを低速クエリログに登録します。これは、遅いクエリを探して、どれくらいの頻度で遅いかを調べるのに理想的な場所です。

    遅いクエリログは通常、/ var / log / mysql / mysql-slow.log

    にあります。

    mysqld.cnfで低速クエリのロギングを設定して有効にする必要がある場合があることに注意してください。 構成ファイルは次のとおりです。

    #slow_query_log = 1
    #slow_query_log_file = /var/log/mysql/mysql-slow.log
    #long_query_time = 2 
    

    MySQL 5以前およびMySQL5では、特にきめ細かいロギングのサポートが不足しているという深刻な制限がありました。休息だけが、ロギングを有効にするパッチを使用していました。ただし、この機能は、コア機能の一部としてMySQL5.1以降のサーバーの一部になっています。

    実行に時間がかかりすぎるクエリは、必ずしも悪いクエリであることを意味するわけではありません。遅いクエリログは、クエリのパフォーマンスを調べて可能な限り改善する機会を提供するだけです。

    リストラクエリ

    問題のあるクエリを再構築する機会があるため、主な目的は、必要な効果を達成するための代替ソリューションを見つけることです。処理中のMySQLサーバーの内部効果を念頭に置いて、クエリを同等の形式に変換できます。

    クエリ設計における1つの決定は、いくつかの単純なクエリの代わりに1つの複雑なクエリを優先するか、またはその逆を行うかです。データベース設計の従来のアプローチは、より少ないクエリで可能な限り多くの作業を行うことです。その理由は、データベース接続を確立するという点で、1つの大きな/複雑なクエリの方が費用効果が高いためです。複雑なクエリを優先するコスト削減の利点は、ネットワークの使用、クエリの処理/最適化、およびリソースの使用率です。しかし、この従来のアプローチはMySQLには適していません。 MySQLは、データベースの接続と切断を迅速に処理するように設計されています。したがって、接続を確立し、多くの単純なクエリを実行し、接続を閉じる方が効率的であるように思われます。 1つの大きな複雑なクエリの代わりに、複数の単純なクエリを介してデータを取得する方が効果的です。同じ考え方が他のデータベースに適用されない場合があることに注意してください。

    結論

    これらは、クエリの最適化に関するいくつかの簡単なヒントです。 SQL構文を知っていると、クエリのパフォーマンスを目的とする場合、目的の結果を取得するクエリを作成するだけでは不十分であることを理解してください。一見単純に見えるクエリの下で起こっていることを理解することは、必要なものを取得するだけでなく、すべてが始まるところから最適化の技術を吹き込むクエリを作成する上で不可欠です。クエリ処理の舞台裏で行われることは、クエリのパフォーマンスを理解するための重要な手がかりを与えます。この知識は、クエリ最適化の領域に進出する前に必須です。


    1. MySQLでJSONデータを検索する方法は?

    2. データベーススキーマオブジェクトチェックの自動化

    3. Oracleデータベースで即時実行するALTER&DROPテーブルDDL

    4. DTCにエスカレーション/スパンせずにSQLServerとOracleの両方のEFとTransactionScope?