この記事では、PHPデータベースプログラミングのMySQL最適化戦略について簡単に説明します。次のように、参照用にあなたと共有してください:
数日前に、PHPのボトルネックは、多くの場合、PHP自体ではなく、データベースにあるという記事を見ました。PHPの開発では、データの追加、削除、変更、およびチェックがコアであることは誰もが知っています。PHPの運用効率を向上させるために、プログラマーは論理的に明確で効率的なコードを記述するだけでなく、クエリステートメントを最適化することもできます。私たちはデータベースの読み取りと書き込みの速度に無力ですが、memcache、mongodb、redis、その他のデータストレージサーバーなどのいくつかのデータベース拡張機能の助けを借りて、PHPはより速いアクセス速度を達成することもできるので、理解して学びますこれらの拡張機能も非常に必要です。この記事では、最初にMySQLの一般的な最適化戦略について説明します。
MySQLのヒント
1. SQLステートメントのキーワードは大文字で書くのが最適です。まず、キーワードと操作オブジェクトを簡単に区別できます。次に、SQLステートメントが実行されると、MySQLはそれらを大文字に変換します。手動大文字はクエリの効率を高めることができます(小さいですが)。
2.データベースのデータ行を追加または削除すると、データIDが大きくなりすぎます。ALTER TABLE tablename AUTO_INCREMENT=N
これを使用して、IDをNから自動インクリメントします。
3、タイプintZEROFILL
属性データを追加するには、自動的に0を入力できます
4.大量のデータをインポートする場合は、最初にインデックスを削除し、データを挿入してからインデックスを追加することをお勧めします。そうしないと、mysqlはインデックスの更新に多くの時間を費やします。
5. sqlステートメントを書き込むためのデータベースを作成する場合、IDEで.sqlのサフィックスが付いたファイルを作成できます。IDEはsql構文を認識するため、書き込みが簡単になります。さらに重要なことに、データベースが失われた場合でも、このファイルを見つけて現在のディレクトリで使用/path/mysql -uusername -ppassword databasename < filename.sql
し、ファイル全体のsqlステートメントを実行できます(-uと-pの後にスペースなしでユーザー名とパスワードが続くことに注意してください)。
データベース設計の最適化
1.データベースの設計は3番目のパラダイムに準拠しており、クエリの利便性のためにある程度のデータの冗長性があります。
2.データタイプpriorityint> date、time> enum、char> varchar> blobを選択します。データタイプを選択するときは、置き換えることを検討してください。たとえば、ストレージ用のip2long()関数を使用して、ipアドレスをunsignintタイプに変換できます。
3. char(n)タイプの場合、データが完成したときにnの値をできるだけ小さくする必要があります。
4.テーブルを作成するときにpartitionコマンドを使用して単一のテーブルをパーティション化すると、クエリの効率が大幅に向上します。MySQLは、RANGE、LIST、HASH、およびKEYパーティションタイプをサポートします。その中で、RANGEが最も一般的に使用され、パーティション化方法は次のとおりです。
CREATE TABLE tablename{
}ENGINE innodb/myisam CHARSET utf8 //选择数据库引擎和编码
PARTITION BY RANGE/LIST(column),//按范围和预定义列表进行分区
PARTITION partname VALUES LESS THAN /IN(n),//命名分区并详细限定分区的范围
5.データベースエンジンを選択するときは、innodbとmyisamの違いに注意してください。
ストレージ構造:MyISAMは3つのファイルとしてディスクに保存されます。すべてのInnoDBテーブルは同じデータファイル(通常は2GB)に保存されます
トランザクションサポート:MyISAMはトランザクションサポートを提供しません。InnoDBは、トランザクションサポートトランザクションを提供します。
テーブルロックの違い:MyISAMはテーブルレベルのロックのみをサポートします。InnoDBは、トランザクションと行レベルのロックをサポートします。
フルテキストインデックス作成:MyISAMは、 FULLTEXTタイプのフルテキストインデックス作成をサポートしています(中国語には適用されないため、sphinxフルテキストインデックス作成エンジンを使用してください)。InnoDBはサポートしていません。
テーブル内の特定の行数:MyISAMはテーブル内の行の総数を保存し、クエリカウント(*)は高速です。InnoDBはテーブルの行の総数を保存しないため、再計算する必要があります。
外部キー:MyISAMはサポートしていません。InnoDBのサポート
インデックスの最適化
1. Innodbはクラスター化されたインデックスです。インデックスを保存するときは、プライマリキーが必要です。指定しない場合、エンジンは自動的に非表示のプライマリキーを生成し、プライマリインデックスを生成します。プライマリキーの物理アドレスはインデックスに保存されます。データはプライマリキーによって保存されます。インデックスを使用する場合は、最初にメインインデックスを見つけてから、メインインデックスの下にあるデータを見つけます。
利点は、プライマリキーの検索が特に高速であるということですが、欠点は、セカンダリインデックス(セカンダリインデックス内のプライマリインデックスの位置)からプライマリインデックスを見つけてから、プライマリインデックスからデータを見つける必要があるため、セカンダリインデックスが遅くなることです。また、主キーが不規則な場合は、新しい値を挿入するときにさらに多くのデータブロックを移動する必要があり、効率に影響するため、定期的に増加するintタイプを主キーとして使用してみてください。また、データは主キーの直後に配置されるため、データに特に大量のデータを含む列(テキスト/ブロブ)がある場合、innodbクエリは多くのデータブロックをスキップし、これも速度低下の原因になります。
2. myisamのインデックスはすべて同じであり、ディスク上の各行のアドレスを均一に指します。これらはすべて軽量のポインターデータです。欠点は、各インデックスの確立がプライマリキーを介して行われないこと、およびクエリがプライマリキーを見つけるためのクラスタ化されたインデックスほど高速ではないことです。ただし、アドレスが格納されているため、新しい値を挿入すると比較が変わります。
3.複数条件クエリを実行する場合、複数の条件に個別にインデックスを付ける場合、sqlクエリを実行する場合、MySQLは使用する最も近いインデックスのみを選択するため、複数条件クエリが必要な場合は、データの冗長性が発生する場合でも、共同インデックスを作成する必要があります。もっと。
共同インデックスのBTREE確立方法:最初の条件にインデックスを付け、最初のインデックスのBTREE領域で2番目の条件にインデックスを付けるなど、インデックスを使用するときは、最初の条件を使用せず、2番目の条件を使用しますこの条件では、ジョイントインデックスは使用されません。インデックスを使用する場合は、条件を順番に並べて使用する必要があります。
4.インデックスの長さもクエリに大きな影響を与えます。短いインデックス長を作成する必要があります。クエリ列
SELECTCOUNT(DISTINCT LEFT(column))/ COUNT(*)FROM tablenameを使用して、列列にインデックスを付けるときに選択をテストできます。さまざまな長さ、インデックスのカバレッジの大きさ、飽和に近いn個の長さを選択して、インデックスを作成し
ます。ALTERTABLEtablename ADD INDEX(column(n));列の最初のn文字にインデックスを付けます。最初のn文字が同じである場合は、文字列の格納を逆にして、インデックスを作成することもできます。
5.頻繁な変更によって引き起こされるインデックスの断片化の保守方法:ALTER TABLE tablename ENGINE oldengine;つまり、テーブルストレージエンジンを再度適用して自動的に保守します。保守にはOPTIMIZEtablenameコマンドを使用することもできます。
データクエリの最適化
データベース操作を最小限に抑え、クエリがある場合はデータベースレベルでデータ操作を実行しないようにしますが、PHPスクリプトに戻ってデータを操作し、データベースの負荷を軽減します。
データベースのパフォーマンスの問題が発見されたら、時間内に解決する必要があります。通常、遅いクエリログは「遅い」クエリの記録に使用され、EXPLAINはクエリとインデックスの使用状況の分析に使用され、PROFILEはステートメント実行中の特定のリソース消費の分析に使用されます。
遅いクエリログ:
1.my.iniまたはmy.cnfの[mysqld]の下に追加します
-
slow_query_log_file = / path //ログストレージパスを設定します
-
long_query_time = n //ステートメントの実行時間がn秒に達すると設定され、記録されます
2.次に、MySQLでSET slow_query_log = 'ON'を設定して、低速クエリを有効にします。
3.ログを記録した後、/ bin /ディレクトリのmysqldumpslowファイル名を使用してログを表示します。一般的なパラメータは次のとおりです。
-
-gパターンは正規表現を使用します
-
-tnは最初のn個のデータを返します
-
-sc / t / l / rレコード時間/時間/クエリ時間/返されたレコード番号で並べ替え
EXPLAINステートメント
使用方法、実行するクエリステートメントの前にEXPLAINを追加します
EXPLAIN SELECT * FROM user;
結果は次のとおりです。
各項目の説明は次のとおりです。
idクエリステートメントのID。単純なクエリは無意味であり、クエリの実行順序は複数のクエリで確認できます。
select-typeによって実行されるクエリステートメントのタイプは、simple / primary / unionなどの複数のクエリに対応します。
Tabelクエリステートメントクエリデータテーブル
type取得されたデータのタイプ、高から低への一般的なタイプ効率はnull> const> eq_ref> ref> range> index> allです
可能なキー:可能なインデックス
キーが使用するインデックス
key_lenインデックスの長さ
どの列refがインデックスと一緒に使用してテーブルから選択するか。
Rowsは、スキャンするデータのおおよその行数を検出します。インデックスの長所と短所を確認できます。
特別に一般的なものは
filesortを使用して、データをクエリした後にファイルを並べ替えます。これは遅く、インデックスを最適化する必要があります
whereを使用すると、データの行全体が読み取られ、where条件を満たしているかどうかが判断およびフィルタリングされます。
インデックスインデックスカバレッジを使用すると、つまり、ターゲットデータはすでにトラクションに格納されており、インデックスは非常に高速に直接読み取られます。
プロフィール
SELECT @@ frofilingを使用して、PROFILEのオン状態を表示します。
オンになっていない場合は、SET profiling = 1を使用してオンにします。
開いてクエリステートメントを実行すると、MySQLはプロファイル情報を自動的に記録します。
show profileを使用して、すべてのsql情報を表示すると、結果はQuery_IDデュレーションです。クエリID、時間、および使用されたSQLステートメントである結果の3列をクエリします。
使用できます
SHOW PFROFILE [type[,type]][FOR QUREY Query_ID][Limit rwo_count [OFFSET offset]]
一般的なタイプには、ALL(すべて)、BLOCK IO(IO関連のオーバーヘッドの表示)、CPU(CPUオーバーヘッド)、MEMORY(メモリオーバーヘッド)などがあります。
大容量ストレージ向けに最適化
データベースのマスタースレーブレプリケーションと読み取り/書き込み分離
1.マスターはバイナリログに変更を記録し、スレーブはマスターのバイナリをリレーログにコピーしてから、データを自身のデータに戻し、マスターサーバーデータをコピーする目的を達成します。
マスタースレーブレプリケーションは、データベースの負荷分散、データベースのバックアップ、読み取りと書き込みの分離、およびその他の機能に使用できます。
2.マスターサーバーマスターを構成します
修改my.ini/my.conf
[mysqld]
log-bin=mysql-bin //启用二进制日志
server-id=102 //服务器唯一ID
3.スレーブを構成します
log-bin=mysql-bin //启用二进制日志
server-id=226 //服务器唯一ID
4.マスターサーバーでスレーブサーバーを承認します
GRANT REPLICATION SLAVE ON *.* to 'slavename'@'IP' identified by 'root'
5.スレーブサーバーで使用する
change master to
master_host="masterip",
master_user="masteruser",
master_password="masterpasswd";
6.次に、start slaveコマンドを使用して、マスタースレーブレプリケーションを開始します。
構成を変更するたびにサーバーを再起動することを忘れないでください。そうすれば、show master / slave statusを使用して、マスタースレーブサーバーのマスター/スレーブステータスを表示できます。
データベースの読み取りと書き込みの分離の実現は、mysql_proxy、atlasなどのMySQLミドルウェアに依存します。マスターサーバーとスレーブサーバーを読み取りと書き込みで分離するようにこれらのミドルウェアを構成することにより、スレーブサーバーは読み取りの責任を負い、マスターサーバーの負担を軽減します。
データベースシャーディング
データベース内のデータテーブル内のデータ量が非常に多い場合、インデックス作成やキャッシングなどのプレッシャーであるかどうかにかかわらず、クエリプレッシャーを軽減するために、データベースは複数のデータベースサーバーまたは複数のテーブルに格納されるようにシャーディングされます。
あり、垂直分割、水平分割と組み合わせてセグメンテーションが。
垂直セグメンテーション:データテーブルが多数ある場合は、密接に関連しているデータベース内のテーブルを分割し(同じモジュール、多くの場合接続されてクエリされるなど)、それらを異なるマスターサーバーとスレーブサーバーに配置します。
水平セグメンテーション:テーブルが少なく、テーブル内のデータ量が非常に多い場合、クエリを高速化するために、ハッシュなどのアルゴリズムを使用してデータテーブルを複数に分割し、それらを異なるサーバーに配置してクエリを高速化できます。 。水平パーティショニングとデータテーブルパーティショニングの違いは、そのストレージメディアにあります。
共同セグメンテーション:ほとんどの場合、データテーブルとテーブルのデータ量が非常に多いため、共同セグメンテーションが必要です。つまり、垂直方向と水平方向のテーブル分割が同時に実行され、データベースが分散マトリックスに分割されて保存されます。
これらのデータベース最適化方法はそれぞれ、広範で深遠な記事を書くために使用できます。これらの方法を理解して覚えた後、必要に応じて意図的に選択して最適化し、高いデータベース効率を実現できます。
注意してください、迷子にならないでください
さて、みなさん、上記はこの記事の全内容です。ここで見ることができるのはすべて才能です。さっきも言ったように、PHPには技術的なポイントがたくさんあります。多すぎるので、書くのは本当に不可能で、書いた後はあまり読まないので、必要に応じてここでPDFとドキュメントに整理します。できる
クリックしてシークレットコードを入力してください:PHP +「プラットフォーム」
学習内容の詳細については、[Comparative Standard Factory]の優れたPHPアーキテクトチュートリアルカタログをご覧ください。給与が確実に上がるように読むことができます(継続的な更新)
上記のコンテンツは、すべての人に役立つことを願っています。多くのPHP担当者は、上級者になると常に問題やボトルネックに直面します。ビジネスコードを書きすぎると、方向性がわかりません。どこから改善を始めればよいかわかりません。これに関する情報をまとめました。ただし、これらに限定されません。分散アーキテクチャ、高スケーラビリティ、高パフォーマンス、高同時実行性、サーバーパフォーマンスチューニング、TP6、laravel、YII2、Redis、Swoole、Swoft、Kafka、Mysql最適化、シェルスクリプト、Docker、マイクロサービス、Nginxなど。多くの知識ポイント、高度な高度な乾物は、誰とでも無料で共有でき、必要な人は私のPHPテクノロジー交換グループに参加できます