私は少しのテーブルを作成しました:
create table dotdotdot (
col varchar(20),
othercol int,
key(col)
);
私はあなたが示したものと類似したクエリにEXPLAINでした:それは、インデックスを使用することはできません
explain select * from dotdotdot where lower(col) = 'value'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: dotdotdot
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 1
filtered: 100.00
Extra: Using where
お知らせtype: ALL
をcol
にあります。 lower()
関数を使用すると、MySQLがインデックスを使用する能力が損なわれ、すべての行の式を評価するテーブルスキャンに頼らざるを得なくなります。あなたのテーブルが大きくなるにつれ、これはますます高価になります。
とにかくそれは不要です!文字列の比較は、デフォルトの照合では大文字と小文字を区別しません。したがって、大文字と小文字を区別する照合またはバイナリ照合を使用してテーブルを意図的に宣言しない限り、lower()
関数呼び出しをスキップするだけでよいので、インデックスを使用できます。
例:
explain select * from dotdotdot where col = 'value'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: dotdotdot
partitions: NULL
type: ref
possible_keys: col
key: col
key_len: 23
ref: const
rows: 1
filtered: 100.00
Extra: NULL
type: ref
非一意のインデックスの使用を示しています。
また、パターンマッチングにワイルドカードを使用する方法と比較してください。これはまた、インデックスの使用を無効にし、テーブルスキャンを実行する必要があります。
パターンマッチングにこのようなワイルドカードを使用すると、非常に効率が悪いです。
代わりにフルテキストインデックスを使用する必要があります。 OR
を使用する場合に役立ちますあなたが求める他の回答ではhttps://www.youtube.com/watch?v=-Sa7TvXnQwY
:
は、あなたは私のプレゼンテーションFull Text Search Throwdown、ここでビデオを好きかもしれません。 それはしません。
explain select * from dotdotdot where col like 'value%' or col like '%value%'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: dotdotdot
partitions: NULL
type: ALL
possible_keys: col
key: NULL
key_len: NULL
ref: NULL
rows: 1
filtered: 100.00
Extra: Using where
お知らせオプティマイザは可能キーとしてCOLインデックスを識別するが、その後最終的に(key: NULL
)を使用しないことを決定します。
次の行に進む前にすべての条件を検査します。あなたは何を意味するのですか?ORはSQLの短絡です。もし最初のようなものが次のものが無視されるならば? – chiperortiz
一致がある場合はyesですが、そうでない場合は一致しません。評価する条件が増えたために得られる利益は失われます。私は私の答えを詳述しました。 – Simon
ありがとう、私の欲しいのは私のパフォーマンスが低下していないことです!クエリが時々パフォーマンスのアップグレードを得ることができる場合は私と一緒にOKです。 – chiperortiz