クエリ用にクエリを最適化する
ほとんどの MySQL サーバーではクエリ キャッシュが有効になっています。これはパフォーマンスを向上させる最も効果的な方法の 1 つであり、MySQL データベース エンジンによって処理されます。同じクエリの多くが複数回実行されると、これらのクエリ結果はキャッシュに配置されるため、後続の同一のクエリではテーブルを操作する必要がなく、キャッシュされた結果に直接アクセスできます。
ここでの主な問題は、プログラマーにとって、この問題が見落とされやすいことです。クエリ ステートメントによっては MySQL がキャッシュを使用しなくなるためです。次の例を見てください:
// 查询缓存不开启 $r = mysql_query("SELECT username FROM user WHERE signup_date >= CURDATE()"); // 开启查询缓存 $today = date("Y-m-d"); $r = mysql_query("SELECT username FROM user WHERE signup_date >= '$today'");
上記 2 つの SQL ステートメントの違いは CURDATE() です。MySQL のクエリ キャッシュはこの関数では機能しません。したがって、NOW() や RAND() などの SQL 関数、またはその他の同様の関数では、クエリ キャッシュが有効になりません。これらの関数の戻り値は揮発性であるためです。したがって、必要なのは、MySQL 関数を変数に置き換えてキャッシュを有効にすることだけです。
EXPLAIN の使用方法を学ぶ
EXPLAIN キーワードを使用すると、MySQL が SQL ステートメントをどのように処理するかを知ることができます。
select id, title, cate from news where cate = 1
クエリが遅いことがわかった場合は、cate フィールドにインデックスを追加すると、クエリが高速化されます。
クエリが 1 行しかない場合は、LIMIT 1 を使用します。 data
テーブルをクエリするときに必要なデータが 1 つだけの場合があるため、制限 1 を使用してください。
インデックスを正しく使用する
インデックスは、必ずしも主キーや一意のフィールドに使用される必要はありません。テーブル内に検索、写真、条件に常に使用するフィールドがある場合は、そのフィールドのインデックスを作成してください。
ORDER BY RAND()
非常に非効率的なランダム クエリです。
SELECT を避ける *
データベースから読み取られるデータが増えるほど、クエリは遅くなります。また、データベースサーバーとWEBサーバーが独立した2台のサーバーの場合、ネットワーク通信の負荷も大きくなります。必要なものは何でも摂取する良い習慣を身につけなければなりません。
VARCHAR の代わりに ENUM を使用してください
ENUM 型は非常に高速でコンパクトです。実際には、TINYINT を保持しますが、文字列として表示されます。このようにして、このフィールドを使用して選択リストを作成するのが非常に完璧になります。
「性別」、「国」、「民族」、「ステータス」、「部門」などのフィールドがあり、これらのフィールドの値が制限され固定されていることがわかっている場合は、その場合は、VARCHAR の代わりに ENUM を使用する必要があります。
NOT NULL の使用
NULL 値を使用する特別な理由がない限り、フィールドは常に NOT NULL のままにしてください。これは少し物議を醸すかもしれませんが、読み続けてください。
まず第一に、「空」と「NULL」(INT の場合は 0 と NULL) の違いは何なのかを自問してください。両者に違いがないと思われる場合は、NULL を使用しないでください。 (ご存知ですか? Oracle では、NULL と空の文字列は同じです!)
NULL にはスペースは必要ありません。追加のスペースが必要です。比較すると、手順はさらに複雑になります。複雑な。もちろん、これは NULL を使用できないという意味ではなく、実際は非常に複雑であり、NULL 値を使用する必要がある状況が依然として存在します。
以下は MySQL 自身のドキュメントからの抜粋です。
「NULL 列には、その値が NULL かどうかを記録するために行に追加のスペースが必要です。MyISAM テーブルの場合、各 NULL 列は 1 ビット余分に必要です」
#IP アドレスは UNSIGNED INT として保存されます
多くのプログラマーは、VARCHAR(15) フィールドを作成して IP を整数の IP ではなく文字列の形式。整数を使用して格納する場合、必要なバイト数は 4 バイトだけであり、固定長フィールドを使用できます。さらに、これは、特に ip1 と ip2 の間の IP のような WHERE 条件を使用する必要がある場合に、クエリに利点をもたらします。 IP アドレスは 32 ビット符号なし整数全体を使用するため、UNSIGNED INT を使用する必要があります。固定長テーブルの方が高速です
テーブル内のすべてのフィールドが「固定長」の場合、テーブル全体が「静的」または「固定長」とみなされます。たとえば、テーブルには VARCHAR、TEXT、BLOB 型のフィールドはありません。これらのフィールドのいずれかを含めている限り、テーブルは「固定長の静的テーブル」ではなくなり、MySQL エンジンは別の方法でテーブルを処理します。 固定長テーブルを使用すると、MySQL の検索が高速になるため、パフォーマンスが向上します。これらの固定長により、次のデータのオフセットの計算が容易になるため、読み取りも自然に高速になります。また、フィールドが固定長でない場合、次のフィールドを検索するたびに、プログラムは主キーを検索する必要があります。 また、固定長テーブルはキャッシュと再構築が容易です。ただし、唯一の副作用は、固定長フィールドは使用するかどうかに関係なく非常に多くのスペースを必要とするため、固定長フィールドによってスペースが浪費されることです。垂直分割
「垂直分割」は、データベース内のテーブルを列ごとに複数のテーブルに変換する方法です。これにより、テーブルの複雑さとフィールドの数が軽減され、それによって最適化の目的が達成されます。この分割されたフィールドで構成されるテーブルを頻繁に結合しないと、分割していない場合よりもパフォーマンスが低下し、極端にパフォーマンスが低下することに注意してください。
大規模な DELETE または INSERT ステートメントを分割する
オンライン Web サイトで大規模な DELETE または INSERT クエリを実行する場合は、操作によって次のような問題が発生しないように十分に注意する必要があります。ウェブサイト全体が応答を停止します。これら 2 つの操作はテーブルをロックするため、テーブルがロックされると、他の操作は入力できなくなります。
Apache には多くの子プロセスまたはスレッドがあります。したがって、非常に効率的に動作し、サーバーは子プロセス、スレッド、データベース リンクが多すぎることを望まないため、多くのサーバー リソース、特にメモリが消費されます。
テーブルを 30 秒などの一定期間ロックすると、アクセス数が多いサイトでは、この 30 秒間にアクセス プロセス/スレッドが蓄積され、データベース リンクが開かれ、ファイルの数が多いと、WEB サービスがクラッシュするだけでなく、サーバー全体がすぐにハングアップする可能性があります。
列が小さいほど高速になります
ほとんどのデータベース エンジンでは、ハードディスク操作が最も大きなボトルネックになる可能性があります。したがって、データをコンパクトにすると、ハード ドライブへのアクセスが減るため、この状況では非常に役立ちます。
適切なストレージ エンジンの選択
MySQL には MyISAM と InnoDB という 2 つのストレージ エンジンがあり、それぞれのエンジンには長所と短所があります。
MyISAM は、多数のクエリを必要とするアプリケーションには適していますが、多数の書き込み操作にはあまり適していません。フィールドを更新するだけの場合でも、テーブル全体がロックされ、読み取り操作が完了するまで他のプロセス (読み取りプロセスであっても) が動作できなくなります。さらに、MyISAM は SELECT COUNT(*) などの計算が非常に高速です。
InnoDB の傾向は非常に複雑なストレージ エンジンになり、一部の小規模なアプリケーションでは MyISAM よりも遅くなるでしょう。もう 1 つの理由は、「行ロック」をサポートしているため、書き込み操作が多い場合に優れていることです。さらに、トランザクションなどのより高度なアプリケーションもサポートします。
以上がMySQL パフォーマンスの最適化に関するある程度の経験の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。