知らない MySQL 最適化の実践は禁止されています (3)



ここに画像の説明を挿入

余計なことは言わず、ただ料理を提供してください。


21. Union all で Union を置き換えてみます。

検索結果に重複レコードが存在しない場合は、unionをunion allに置き換えることをお勧めします。

反例:

select * from user where userid=1 union  select * from user where age = 10

正例:

select * from user where userid=1 union all select * from user where age = 10

理由:

  • Union を使用すると、検索結果が重複しているかどうかに関係なく、最終結果を出力する前にマージしてから並べ替えを試行します。検索結果に重複レコードがないことがわかっている場合は、union の代わりに Union all を使用すると効率が向上します。

22. インデックスは多すぎてはいけません。通常は 5 以内です。

  • インデックスは多ければ多いほど良いのですが、インデックスを使用するとクエリの効率が向上しますが、挿入と更新の効率も低下します。
  • インデックスは挿入または更新中に再構築される可能性があるため、特定の状況に応じてインデックスの構築を慎重に検討する必要があります。
  • テーブル内のインデックスの数は 5 つ以下にするのが最善ですが、多すぎる場合は、一部のインデックスが不要かどうかを検討する必要があります。

23. フィールドに数値情報のみが含まれる場合は、文字型として設計しないようにし、できるだけ数値フィールドを使用するようにしてください。

反例:

`king_id` varchar20NOT NULL COMMENT '守护者Id'

正例:

 `king_id` int(11) NOT NULL COMMENT '守护者Id'

理由:

  • 数値フィールドと比較して、文字型はクエリと接続のパフォーマンスを低下させ、ストレージのオーバーヘッドを増加させます。

24. インデックスは、性別データベース フィールドなど、大量の繰り返しデータを含むフィールドに構築するのには適していません。

SQL オプティマイザーはテーブル内のデータ量に基づいてクエリの最適化を実行するため、インデックス列に大量の重複データがある場合、Mysql クエリ オプティマイザーはインデックスを使用しない方がコストが低いと計算し、インデックスをあきらめる可能性があります。


25. クライアントにあまりにも多くのデータを返さないようにしてください。

ビジネス要件として、ユーザーが過去 1 年間に視聴したライブ ブロードキャスト データの表示を要求するとします。

反例:

//一次性查询所有数据回来select * from LivingInfo where watchId =useId and watchTime >= Date_sub(now(),Interval 1 Y)

正例:

//分页查询select * from LivingInfo where watchId =useId and watchTime>= Date_sub(now(),Interval 1 Y) limit offset,pageSize
//如果是前端分页,可以先查询前两百条记录,因为一般用户应该也不会往下翻太多页,select * from LivingInfo where watchId =useId and watchTime>= Date_sub(now(),Interval 1 Y) limit 200 ;

26. SQL ステートメントで複数のテーブルを接続する場合は、セマンティクスがより明確になるように、テーブルのエイリアスを使用し、各列の先頭にエイリアスを付けてください。

反例:

select  * from A innerjoin B on A.deptId = B.deptId;

正例:

select  memeber.name,deptment.deptName from A member innerjoin B deptment on member.deptId = deptment.deptId;

27. できる限り char/nchar ではなく varchar/nvarchar を使用してください。

反例:

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

正例:

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

理由:

  • 可変長フィールドの記憶領域は小さいため、記憶領域を節約することができる。
  • 次に、クエリの場合は、比較的小さなフィールドで検索する方が効率的です。

28. group by ステートメントの効率を向上させるために、ステートメントを実行する前に不要なレコードをフィルターで除外できます。

反例:

select job,avg(salary) from employee  group by job having job ='president' or job = 'managent'

正例:

select job,avg(salary) from employee where job ='president' or job = 'managent' group by job;

29. フィールドタイプが文字列の場合、where を引用符で囲む必要があります。そうしないとインデックスが失敗します。

反例:

select * from user where userid =123;

ここに画像の説明を挿入

正例:

select * from user where userid ='123';

ここに画像の説明を挿入

理由

  • 最初のステートメントが一重引用符なしでインデックス付けされないのはなぜですか? これは、シングルクォーテーションが付加されていない場合、文字列と数値の比較となり、型が一致しないため、MySQL が暗黙的な型変換を行って浮動小数点数に変換して比較してしまうためです。

30. Explain を使用して SQL プランを分析する

毎日 SQL を開発したり書いたりするときは、できるだけ習慣を身につけるようにしてください。Explain を使用して、作成した SQL、特にインデックスを使用するかどうかを分析します。

explain select * from user where userid =10086 or age =18;

ここに画像の説明を挿入



ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/m0_60915009/article/details/131718910