0

最適化を求める複雑なクエリを含むテーブルがあり、MySQL のインデックス作成に関するほとんどのドキュメントを読みましたが、この場合はどうすればよいかわかりません。

データ構造:

-- please, don't comment on the field types and names, it is outsourced project.

CREATE TABLE items(
  record_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  solid CHAR(1) NOT NULL, -- only 'Y','N' values
  optional CHAR(1) NULL, -- only 'Y','N', NULL values
  data TEXT
 );

クエリ:

SELECT * FROM items
WHERE record_id != 88
AND solid = 'Y'
AND optional !='N'  -- 'Y' OR NULL

もちろん、追加の結合と関連データがありますが、これが最大のフィルターです。

シナリオ:
- 200 000+ レコード、
- 10% (すべてから) solid= 'Y'、
- 10% (すべてから) optional!='N'、

このクエリに適したインデックスは何ですか?
またはより正確には:

  • 最初のチェック レコード != 88 は何らかの方法でクエリを遅くしますか?
    (それは1つの結果だけを排除します...?)

  • どちらが速いか ( optional!='N') または ( 'optional' = 'Y' OR 'optional' is NULL )
    上記の optional= 'N' は合計数の 10% です。

  • 可能な値が 2 つしかない CHAR(1) 列にインデックスを付けるのに特別なことはありますか?

  • このインデックス (record_id、solid、オプション) を使用できますか?

  • 特定の値 (ソリッド = 'Y'、オプション !='N') のインデックスを作成できますか?


@Jack が要求したとおり、現在のEXPLAIN結果 (合計 30 000 行のうち 20 件の結果):

+-------------+-------+--------------+---------+-- -------+------+-------+-------------+
| | select_type | タイプ | 可能な_キー | キー | key_len | 参照 | 行 | 行 エクストラ |
+-------------+-------+--------------+---------+-- -------+------+-------+-------------+
| | プライマリ | 範囲 | プライマリ | プライマリ | 4 | ヌル | 16228 | where | の使用
+-------------+-------+--------------+---------+-- -------+------+-------+-------------+
4

2 に答える 2

3

これは興味深い質問です。全体として、クエリの推定選択性は約 1% です。したがって、100 レコードが 1 ページに収まる場合、インデックスがあっても各ページを読み取る必要があると想定できます。レコードは非常に小さいため (それによって異なりdataます)、これは非常に可能性が高いです。その観点から、インデックスは価値がありません。

次のような状況では、インデックスを使用する価値があります。1 つ目は、インデックスがカバリング インデックスである場合です。つまり、インデックス内のすべての列でクエリを満たすことができます。例えば:

select count(*)
FROM items
WHERE record_id != 88 AND solid = 'Y' AND optional !='N'  -- 'Y' OR NULL

インデックスがある場所solid, optional, record_id。クエリは、元のデータ ページに戻る必要はありません。

もう 1 つのケースは、インデックスがプライマリ (またはクラスター化) インデックスである場合です。データはその順序で格納されるため、限られた数の結果をフェッチすると、クエリの読み取りオーバーヘッドが削減されます。これの欠点は、データを実際に移動する必要があるため、更新と挿入のコストが高くなることです。

dataあなたの場合、インデックスが非常に大きくない限り(キロバイト範囲)、インデックスは役に立たないというのが私の最善の推測です。

于 2013-09-02T15:23:11.467 に答える
0

最も差別化を行う列にインデックスを配置するようにしてください。通常、データベースが値間でほぼ均等に分割されている場合、バイナリ列のインデックス作成はあまり役に立ちません。しかし、頻繁に検索する値が 10% の確率でしか表示されない場合、それは有用なインデックスになる可能性があります。

いずれかの列にインデックスが付けられている場合、通常は他のWHERE処理を行う前にチェックされます。WHERE句に条件を入れる順序は、通常は関係ありません。を使用EXPLAINして、クエリが使用するインデックスを確認できます。

于 2013-09-02T15:24:41.943 に答える