MySQLの仕様とパフォーマンスの最適化

1. SQLを記述した後、最初に実行計画を表示するように説明します(SQLパフォーマンスの最適化)

日常的にSQLを開発および作成するときは、次の良い習慣を身に付けてください。SQLを作成した後、explainを使用して分析し、インデックスを使用するかどうかに特に注意してください。

2.削除または更新ステートメントを操作し、制限を追加します(SQL後悔薬)

  • 「誤って記述されたSQLのコストを削減する」。コマンドラインでこのSQLを実行するときに、制限を追加しないと、実行中に「誤ったハンドシェイク」が発生し、すべてのデータが削除される可能性があります。「間違って削除」するとどうなりますか?制限200を追加すると、それは異なります。エラーの削除は200個のデータの損失のみであり、binlogログを介して迅速に回復できます。

  • 「SQL効率が高くなる可能性が高い」、SQL行に制限1を追加し、最初の行がターゲットリターンに到達した場合、制限がない場合、スキャンテーブルは引き続き実行されます。

  • 「長いトランザクションを避ける」。削除が実行されるときに、ageがインデックスを追加すると、MySQLはすべての関連行に書き込みロックとギャップロックを追加し、すべての実行関連行がロックされます。削除の数が多い場合、関連ビジネスに直接影響します。利用不可。

  • 「データ量が多いとCPUが いっぱいになりやすい。」大量のデータを削除する場合は、レコード数を制限しないでください。cpuがいっぱいになりやすく、削除が遅くなります。

3.テーブルを設計するときに、対応するコメントをすべてのテーブルとフィールドに追加します(SQL仕様は洗練されています)

この良い習慣を身に付ける必要があります。データベーステーブルを設計するときは、すべてのテーブルとフィールドに対応するコメントが追加されるため、後で保守しやすくなります。

「反例:」

CREATE TABLE `account` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `balance` int(11) DEFAULT NULL,
  `create_time` datetime NOT NULL ,
  `update_time` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1570068 DEFAULT CHARSET=utf8;

「正例:」

CREATE TABLE `account` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键Id',
  `name` varchar(255) DEFAULT NULL COMMENT '账户名',
  `balance` int(11) DEFAULT NULL COMMENT '余额',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  `update_time` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1570068 DEFAULT CHARSET=utf8 ROW_FORMAT=REDUNDANT COMMENT='账户表';

4. SQL書き込み形式、キーワードサイズの一貫性を保ち、インデントを使用します。(SQL仕様はエレガントです)

「反例:」

SELECT stu.name, sum(stu.score) from Student stu WHERE stu.classNo = '1班' group by stu.name.

「正例:」

SELECT stu.name, sum(stu.score)
FROM Student stu
WHERE stu.classNo = '1班'
GROUP BY stu.name

5. INSERTステートメントは、対応するフィールド名を示します(SQL仕様エレガント)

「反例:」

insert into Student values ('666','捡田螺的小男孩','100');

「正例:」

insert into Student(student_id,name,score) values ('666','捡田螺的小男孩','100');

 6.変更されたSQL操作は、最初にテスト環境で実行され、詳細な操作手順とロールバックプランが作成され、本番前に確認されます。(SQL後悔医学)

  • 変更されたSQL操作は、構文エラーを回避して本番環境に移行するために、最初にテスト環境でテストされます。

  • Sql操作を変更するには、特に次のような依存関係がある場合に、詳細な操作手順を指定する必要があります。最初にテーブル構造を変更してから、対応するデータを追加します。

  • SQL操作を変更するためのロールバック計画があり、本番前に、対応する変更SQLを確認します。

7.データベーステーブルを設計するときに、プライマリキー、create_time、update_timeの3つのフィールドを追加します。(SQL仕様はエレガントです)

「反例:」

CREATE TABLE `account` (
  `name` varchar(255) DEFAULT NULL COMMENT '账户名',
  `balance` int(11) DEFAULT NULL COMMENT '余额',
) ENGINE=InnoDB AUTO_INCREMENT=1570068 DEFAULT CHARSET=utf8 ROW_FORMAT=REDUNDANT COMMENT='账户表';

「正例:」

CREATE TABLE `account` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键Id',
  `name` varchar(255) DEFAULT NULL COMMENT '账户名',
  `balance` int(11) DEFAULT NULL COMMENT '余额',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  `update_time` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1570068 DEFAULT CHARSET=utf8 ROW_FORMAT=REDUNDANT COMMENT='账户表';

「理由:」

  • 主キーは通常追加されますが、主キーのないテーブルには魂がありません

  • 作成時間と更新時間を追加することをお勧めします。詳細な監査と追跡の記録はすべて役に立ちます。

図に示すように、Ali開発マニュアルにもこの点が記載されています。

8. SQLステートメントを記述した後、where、order by、group byの背後にある列、および複数のテーブルに関連付けられた列にインデックスが付けられているかどうかを確認します。結合されたインデックスが優先されます。(SQLパフォーマンスの最適化)

 「反例:」

select * from user 
where address ='深圳' order by age;

「正例:」

添加索引
alter table user add index idx_address_age (address,age)

 

9.重要なデータを変更または削除する前に、バックアップ、最初にバックアップ、最初にバックアップ(SQL後悔医学)

データを変更または削除する場合は、SQLを実行する前に、変更するデータをバックアップする必要があります。誤操作の場合でも、「後悔の薬」をかじることができます

10. whereの背後にあるフィールドは、そのデータタイプの暗黙的な変換に注意を払います(SQLパフォーマンスの最適化)

「反例:」

//userid 是varchar字符串类型
select * from user where userid =123;

「正例:」 

select * from user where userid ='123';

「理由:」

一重引用符が追加されていない場合、文字列と数値の比較であり、型が一致しないため、MySQLは暗黙的な型変換を行い、浮動小数点数に変換してから比較し、最終的にインデックスを失敗させます。

11.すべての列をNOTNULLとして定義してみてください(SQL仕様は洗練されています)

  • 「NOTNULL列はより多くのスペースを節約します。」 NULL列は、NULLかどうかを判断するためのフラグビットとして追加のバイトを必要とします。

  • 「NULL列はヌルポインタの問題に注意を払う必要があります」。NULL列を計算および比較するときは、ヌルポインタの問題に注意を払う必要があります。

12. SQLを変更または削除するには、最初にWHEREを記述して確認し、確認後に削除または更新を追加します(SQL後悔医学)

特に、生成されたデータを操作するときに、変更または削除されたSQLが発生した場合は、最初にwhereクエリを追加し、[OK]を確認してから、更新または削除操作を実行します。

13. select *の代わりにselect <specific field>を使用するなど、不要なフィールドリターンを減らします(SQLパフォーマンスの最適化)

「反例:」

select * from employee;

「正例:」

select id,name from employee;

理由:

  • リソースを節約し、ネットワークのオーバーヘッドを削減します。

  • カバーインデックスは、バックテーブルを減らし、クエリの効率を向上させるために使用できます。

14.すべてのテーブルでInnodbストレージエンジンを使用する必要があります(SQL仕様エレガント)

Innodbは、  「トランザクションをサポートし、行レベルのロックをサポートし、回復性を向上させます。」高い同時実行性でパフォーマンスが向上するため、特別な要件はありません(つまり、列ストレージ、ストレージスペースデータなど、Innodbが満たすことができない機能)。 、すべてのテーブルでInnodbストレージエンジンを使用する必要があります

15.データベースとテーブルの文字セットにUTF8を均一に使用するようにしてください(SQL仕様は洗練されています)

UTF8エンコーディングを均一に使用してみてください

  • 文字化けの問題を回避できます

  • 異なる文字セットの比較と変換によって引き起こされるインデックス障害の問題を回避できます

「エモチコンを保存する必要がある場合は、保存するutf8mb4を選択し、それとutf-8エンコーディングの違いに注意してください。」

begin;
update account set balance =1000000
where name ='捡田螺的小男孩';
commit;

16.charの代わりにvarcharを使用してみてください。(SQLパフォーマンスの最適化)

「反例:」

 `deptName` char(100) DEFAULT NULL COMMENT '部门名称'

「正例:」

`deptName` varchar(100) DEFAULT NULL COMMENT '部门名称'

理由:

  • 可変長フィールドのストレージスペースが小さいため、ストレージスペースを節約できます。

17.フィールドの意味を変更したり、フィールドの状態に追加したりする場合は、フィールドのコメントを時間内に更新する必要があります。(SQL仕様はエレガントです)

この点は、Ali開発マニュアルのMysqlプロトコルです。フィールド、特に列挙ステータスを表す場合、意味が変更された場合、またはステータスが追加された場合は、後でメンテナンスしやすくするために、フィールドのコメントをすぐに更新する必要があります。

18.データを変更し、トランザクションの開始とコミットの習慣を身に付けるためのSQLコマンドライン(SQL後悔医学)

「反例:」

update account set balance =1000000
where name ='捡田螺的小男孩';

「正例:」

begin;
update account set balance =1000000
where name ='捡田螺的小男孩';
commit;

19.インデックスの命名は標準化する必要があり、プライマリキーインデックスはpk_フィールド名、一意のインデックスはuk _フィールド名、通常のインデックス名はidx_フィールド名です。(SQL仕様はエレガントです)

説明:pk_はプライマリキー、uk_は一意のキー、idx_はインデックスの省略形です。

20.関数変換と式の計算は、WHERE句の列では実行されません。

loginTimeにインデックスが付けられていると仮定します

「反例:」

select userId,loginTime 
from loginuser
where Date_ADD(loginTime,Interval 7 DAY) >=now();

「正例:」

explain  select userId,loginTime 
from loginuser 
where  loginTime >= Date_ADD(NOW(),INTERVAL - 7 DAY);

「理由:」

インデックス列でMySQLの組み込み関数を使用すると、インデックスが無効になります

21.変更/更新が多すぎる場合は、バッチ処理を検討してください。

「反例:」

delete from account  limit 100000;

「正例:」

for each(200次)
{
 delete from account  limit 500;
}

「理由:」

  • 大規模なバッチ操作では、マスタースレーブの遅延が発生します。

  • 大規模な操作では、大規模なトランザクションとブロックが生成されます。

  • 大規模な操作とデータが多すぎると、cpuがいっぱいになります。

 

前:Oracleデータベースアクセスパフォーマンスの最適化

次へ:PostgreSQLデータベースのバックアップとリカバリ

 

転載:https//blog.csdn.net/weiwenhou/article/details/109505984

 

おすすめ

転載: blog.csdn.net/guorui_java/article/details/111302048