1

私はこのクエリを持っています:

SELECT 
    COUNT(*) AS `numrows` 
FROM (`tbl_A`) 
JOIN `tbl_B` ON `tbl_A`.`B_id` = `tbl_B`.`id` 
WHERE 
    `tbl_B`.`boolean_value` <> 1;

に3つのインデックスを追加しましたtbl_AB_idtbl_Bidおよびtbl_Bboolean_valueただし、mysqlは(インデックスログを使用しないクエリでは)インデックスを使用しないと言っており、テーブル全体を調べて結果を取得します。

このクエリを最適化するために何をすべきかを知る必要があります。

編集:

出力の説明:

id  select_type table  type  possible_keys          key   key_len  ref      rows  Extra 
1    SIMPLE     tbl_B  ALL   PRIMARY,boolean_value  NULL  NULL     NULL     5049  Using where
1    SIMPLE     tbl_A  ref   B_id                   B_id  9        tbl_B.id 9     Using where; Using index
4

2 に答える 2

0

それboolean_valueが本当にブール値のインデックス付けである場合は、あまり良い考えではありません。インデックスは効果的ではありません。

于 2012-07-11T08:41:14.343 に答える
0

Explainは、tbl_Bに結合するためにインデックスが使用されているが、ブール値でtbl_Aをフィルタリングするためにインデックスが使用されていないことを示しています。

インデックスは利用可能でしたが、エンジンはそれを使用しないことを選択しました。なぜそれが起こるのか:

  • おそらく5049行は大したことではなく、エンジンは、インデックスを使用して、インデックスを使用して行の10%のようなものをフィルタリングすると、それを使用しない場合と同じくらい高速になることを認識しました
  • ブール値は、1、0、またはNULLの3つの値のみを取ります。したがって、インデックスのカーディナリティは常に非常に低くなります(最大3)。カーディナリティの低いインデックスは、通常、クエリアナライザによって削除されます(これは、通常、このインデックスがあまり役に立たないと考えている場合は非常に正しいです)

このブール値のtrue値とfalse値が50/50に再分割されている場合、またはFalseがわずかしかない場合に、クエリアナライザーが同じように動作するかどうかを確認するのは興味深いことです。

現在、ブールフィールドは通常、複数のキーを含むインデックスでのみ役立ちます。そのため、クエリでインデックスのすべてのフィールドを(whereまたはorder byで)使用する場合、クエリアナライザはそのインデックスが本当に優れたツールであると信頼します。

インデックスは書き込みを遅くし、余分なスペースを必要とすることに注意してください。無駄なインデックスを追加しないでください。logt-query-not-using-indexesを使用するのは良いことですが、そのログ情報を遅いクエリログで補正する必要があります。クエリが速い場合は問題ありません。

于 2012-07-11T13:49:59.467 に答える