7

1-セカンダリインデックスで使用されます。たとえば、( 、)PRIMARYのセカンダリインデックスPRIMARYcolumn1

2-範囲スキャンに一部が使用されるとすぐに、mysqlがインデックスの残りの部分を使用し続けることができないことを知っていますがIN (...,...,...)、範囲とは見なされませんか?はい、それは範囲ですが、私はmysqlperformanceblog.comで、インデックスの使用によるとINは異なる動作をすることを読みました。BETWEEN

誰かがそれらの2つのポイントを確認できますか?または、なぜこれが不可能なのか教えてください。またはそれはどのように可能でしょうか?

アップデート:

リンク:
http ://www.mysqlperformanceblog.com/2006/08/10/using-union-to-implement-loose-index-scan-to-mysql/
http://www.mysqlperformanceblog.com/2006/08/ 14 / mysql-followup-on-union-for-query-optimization-query-profiling / comment-page-1 /#comment-952521

更新2:ネストされたSELECTの例:

SELECT * FROM user_d1 uo 
WHERE EXISTS (
    SELECT 1 FROM `user_d1` ui
    WHERE ui.birthdate BETWEEN '1990-05-04' AND '1991-05-04'
    AND ui.id=uo.id
)    
ORDER BY uo.timestamp_lastonline DESC
LIMIT 20

したがって、外側SELECTtimestamp_lastonline並べ替えに使用され、内側PKは外側に接続するかbirthdateフィルタリングに使用されます。

MySQLが範囲スキャンと並べ替えにインデックスを使用できない場合、このクエリ以外にどのようなオプションがありますか?

4

3 に答える 3

2

主キーの列は確かに二次インデックスで使用できますが、多くの場合、価値がありません。主キーは一意性を保証するため、その後にリストされている列は範囲検索に使用できません。クエリがインデックスのみを使用できる場合にのみ役立ちます

ネストされた選択に関しては、余分な複雑さは最も単純なクエリに勝るものではありません。

SELECT * FROM user_d1 uo 
WHERE uo.birthdate BETWEEN '1990-05-04' AND '1991-05-04'
ORDER BY uo.timestamp_lastonline DESC
LIMIT 20

MySQLは、より少ない行をスキャンする可能性が最も高いと思われるbirthdateインデックスまたはインデックスのいずれかを選択します。timestamp_lastonlineいずれの場合も、列はインデックスの最初の列である必要があります。インデックスにはbirthdate並べ替えのペナルティもありますが、最近のユーザーの多くがその範囲外の生年月日を持っている場合は価値があるかもしれません。

順序を制御したい場合、または潜在的にパフォーマンスを向上させたい場合は、(timestamp_lastonline, birthdate)または(birthdate, timestamp_lastonline)インデックスが役立つ場合があります。そうでない場合で、最初に誕生日に基づいて選択する必要がある場合は、フィルタリングするのではなく、内部クエリから選択する必要があります。

SELECT * FROM (
    SELECT * FROM user_d1 ui
    WHERE ui.birthdate BETWEEN '1990-05-04' AND '1991-05-04'
) as uo
ORDER BY uo.timestamp_lastonline DESC
LIMIT 20

それでも、MySQLのオプティマイザは、インデックスは見つかったがtimestamp_lastonlineインデックスが見つからなかった場合にクエリを書き換えることを選択する可能性がありbirthdateます。

そして、はい、とIN (..., ..., ...)は異なる動作をしBETWEENます。後者だけが、インデックスに対して範囲スキャンを効果的に使用できます。前者は各アイテムを個別に検索します。

于 2012-07-03T18:36:11.137 に答える
0

2.IN明らかにとは異なりますBETWEEN。その列にインデックスがある場合はBETWEEN、開始点を取得する必要があり、すべて完了です。がある場合はIN、インデックス値内で値ごとに一致する値を検索するため、BETWEEN1回限りの検索と比較して値の数だけ値を検索します。

于 2012-06-18T09:21:40.927 に答える
0
  1. はい@Andrius_Naruševičiusは正しいですINステートメントはEQUALSまたはEQUALSの省略形ですOREQUALSには固有の順序はありませんが、BETWEENは暗黙の大なり記号または小なり記号を使用する比較演算子であるため、インデックスが大好きです。

  2. 正直なところ、あなたが何について話しているのかわかりませんが、あなたは良い質問をしているようです。私にはそれが何であるかについての概念がありません:-)。主キーに2番目のインデックスを含めることはできないと言っていますか?それは絶対にできるからです。主キーは常に自動的にインデックス付けされるため、インデックス付けする必要はありません。したがって、補足インデックスについてエラー/警告(私はあなたがそうだと思いますか?)を受け取った場合、それは2番目、3番目のインデックスではなく、主キーが必要ない原因になります。それ、そしてあなたはそれがおそらくエラーであると述べています。あなたがどのような質問をしたのか私にはわかりませんが、それはあなたの実際の質問に対する私の最善の推測に対する私の答えです。

于 2012-06-19T17:15:49.643 に答える