1. 一般的な SQL の実践例
(1) 否定条件付きクエリではインデックスを使用できません
select * from order where status!=0 and stauts!=1
存在しない/存在しないというのは良い習慣ではありません
はクエリのように最適化できます:
select * from order where status in(2,3)
(2) 先頭のファジー クエリではインデックス
select * from order where desc like '%XX'
を使用できませんが、非先頭のファジー クエリでは次のことができます:
select * from order where desc like 'XX%'
( 3) データの区別がほとんどないフィールドにインデックスを使用するのは適切ではありません
select * from user where sex=1
理由: 性別は男性と女性のみであり、毎回フィルターで除外されるデータは非常に少ないため、インデックスの使用は適切ではありません。 。
経験上、データの 80% をフィルタリングできる場合にはインデックスを使用できます。注文ステータスについては、ステータス値が少ない場合はインデックスを使用するのは適切ではありませんが、ステータス値が多く、大量のデータをフィルタリングできる場合はインデックスを確立する必要があります。
(4) 属性の計算はインデックスにヒットできません
select * from order where YEAR(date) < = '2017'
日付にインデックスが確立されている場合でも、テーブル全体がスキャンされ、値の計算を最適化できます:
select * from order where date < = CURDATE()
または:
select * from order where date < = '2017-01-01'
2. あまり知られていない SQL プラクティス
(5) ビジネスのほとんどが単一のクエリである場合、ユーザー センターなどのハッシュ インデックスを使用する方が良いです
select * from user where uid=? select * from user where login_name=?
理由:
B ツリー インデックスの時間計算量は O(log(n))
ハッシュ インデックスの複雑さは O(1)
(6) null が許可されている列にはクエリでの潜在的な落とし穴がある
単一列インデックスには null 値が格納されませんが、複合インデックスには null 値が格納されますすべての null 値は保存されません。列が null であることが許可されている場合、「予期しない」結果セットが得られる可能性があります。
select * from user where name != 'shenjian'
名前が null であることが許可されている場合、インデックスは null 値を保存せず、これらのレコードはは結果セットには含まれません。
したがって、not null 制約とデフォルト値を使用してください。
(7) 複合インデックスの左端のプレフィックスは値の順序ではありません SQL ステートメントの順序は複合インデックスと一致している必要があります
ユーザー センターは、(login_name) の複合インデックスを確立しました、passwd)
select * from user where login_name=? and passwd=? select * from user where passwd=? and login_name=?
はインデックスにヒットできます
select * from user where login_name=?
はインデックスにもヒットできますが、これは複合インデックスの左端のプレフィックスを満たす
select * from user where passwd=?
はインデックスにヒットできませんが、ヒットします。複合インデックスの左端のプレフィックスを満たしていません
( 8) 文字列の代わりに ENUM を使用します
ENUM は TINYINT を節約します。「中国」、「北京」、「技術部門」などの文字列は含めないでください。 " 列挙型。文字列スペースが大きく効率が悪い。低い。
3. ニッチだが便利な SQL プラクティス
(9) 返される結果が 1 つだけであることが明らかな場合、制限 1 を使用すると効率が向上します
select * from user where login_name=?
最適化できる内容:
select * from user where login_name=? limit 1
理由:
結果が 1 つだけであることはわかっていますが、データベースはそれを知りません。それを明確に伝え、カーソルの動きを積極的に停止させます
(10) 計算をデータベース層ではなくビジネス層に置くと、データ CPU の節約に加えて、クエリ キャッシュの最適化にも予期せぬ効果が生じます
select * from order where date < = CURDATE()
これは SQL の良い実践ではありません。次のように最適化する必要があります:
$curDate = date('Y-m-d'); $res = mysql_query( 'select * from order where date < = $curDate');
理由:
データベースの CPU を解放します
複数の呼び出し、受信 SQL は同じであり、クエリ キャッシュを使用できます
(11) 強制的な型変換はテーブル全体に影響します。スキャン
select * from user where phone=13800001234
電話インデックスにヒットすると思いますか?これは大きな間違いです。この記述を変更するにはどうすればよいですか?
最後に、もう 1 つ注意してください。select * は使用せず、必要な列のみを返します。これにより、データ送信量とデータベースのメモリ使用量を大幅に節約できます。
この記事は、php 中国語 Web サイトの mysql チュートリアル 列からのものです。学習へようこそ!
以上があまり知られていない 10 の SQL ステートメント最適化の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。