MySQLが日付フィールドインデックスを使用しない理由の要約

MySQLが日付フィールドインデックスを使用しない理由の要約

背景

テーブルでは、dataTime フィールドは varchar 型に設定され、保存されるデータは日付形式で、フィールドにインデックスが設定されます。しかし、ログ レコードには、このテーブルに関する遅いクエリがあります。クエリステートメントは次のとおりです。
select * from digitaltwin_meteorological where dataTime > '2021-10-15';
EXPLAIN は SQL ステートメントを分析し、SQL ステートメントが完全なテーブルスキャンを実行していることを検出します。 SQL で dataTime インデックス列が使用されるのはなぜですか。また、テーブル全体のスキャンが実行される理由はなぜですか。

探検する

1:当初、dataTime フィールドの型が varchar であると考えられていたため、MySQL は日付のサイズ順ではなく文字列順にインデックスをソートし、範囲クエリを実行するときに日付順にインデックス範囲のパーティション分割を実行できませんでした。そこで、dataTime を datatime 型に変更してステートメントを分析したところ、依然として完全なテーブルスキャンが行われていることがわかりました。

2:クエリ条件の値を変更する

 digitaltwin_meteorological から count(*) を選択します。ここで、dataTime > '2021-10-15' です。

実行結果は3910です。

EXPLAIN デジタルツインのmeteorologicalから*を選択し、dataTime > '2021-10-15'を選択します。

SQL ステートメントの分析結果は、完全なテーブルスキャンです。

ここに画像の説明を挿入

レコードの数を確認するために、クエリ条件を 16 に変更します。

 digitaltwin_meteorological から count(*) を選択します。ここで、dataTime > '2021-10-16' です。

クエリ結果は 2525 です。16 番のクエリ ステートメントを分析してみましょう。

EXPLAIN デジタルツインのmeteorologicalから*を選択し、dataTime > '2021-10-16'を選択します。

実行結果は、インデックスを使用する範囲クエリです。

ここに画像の説明を挿入

このことから、クエリされるレコードの数が多い場合、MySQL はフル テーブル スキャンの方が効率的であると判断してフル テーブル スキャンを実行することがわかります。クエリ内のレコードが少ない場合、MySQL はインデックス クエリを使用します。
テーブル内のデータの総量は 19714 レコードです。つまり、2525/19714 = 13% の場合、MySQL はインデックス クエリを使用します。 3910/19714=20% の場合、MySQL は完全なテーブルスキャンを実行します。

3: dataTime を datetime データ型に変更した場合、クエリ条件に引用符を追加する必要がありますか? dataTime クエリ条件の引用符を削除して結果を確認します。

EXPLAIN digitaltwin_meteorological から * を選択し、dataTime > 2021-10-16 を指定します。

ここに画像の説明を挿入
引用符を削除すると、再び完全なテーブルスキャンになることがわかります。したがって、フィールド タイプが varchar か datetime かに関係なく、クエリ条件の値は引用符で囲む必要があります。引用符がない場合、MySQL はこの値に対して何らかの計算を実行します。実際、引用符がない場合、2021-10-16 は 16 日の日付ではなくなります。次の SQL を見てみましょう。

 digitaltwin_meteorological から count(*) を選択します。ここで、dataTime > 2021-10-16 です。

計算結果は 19714 となり、これはテーブル全体のデータです。そのため、datetime クエリ条件も引用符で囲む必要があります。

4: 上記の分析はすべて、datetime 型の場合の dataTime に関するものです。元のフィールド タイプは varchar なので、これを varchar タイプに変更すると、上記の結論は依然として当てはまりますか? タイプを変更して、SQL を再度実行します。

EXPLAIN select * from digitaltwin_meteorological where dataTime > '2021-10-16';

ここに画像の説明を挿入

varchar 型に変更すると、クエリ 16 は範囲スキャンではなくフル テーブル スキャンになることがわかります。
条件を 17 番に変更して実行結果を確認します。

EXPLAIN デジタルツインのmeteorologicalから*を選択し、dataTime > '2021-10-17'を選択します。

ここに画像の説明を挿入

17日のクエリではインデックスクエリが使用されました。 17日のデータ量は1749であることがわかります。
したがって、フィールド タイプが varchar の場合、1749/19714 = 9% のケースでインデックスが使用され、2525/19714 = 13% のケースでテーブル全体がスキャンされます。
つまり、データ型が datetime の場合、クエリ結果がテーブル全体のデータの 13% を占めるとインデックス クエリが実行され、データ型が varchar の場合、クエリ結果がテーブル全体のデータの 13% を占めるとテーブル全体のスキャンが実行されます。これが、日付タイプを varchar ではなく datetime に設定する理由の 1 つです。

要約する

上記の分析を通じて、次のような結論を導き出すことができます。
1. 範囲クエリでは、クエリされるデータの量が特定の範囲に達すると、MySQL は完全なテーブル スキャンの方が効率的であると判断し、インデックスではなく完全なテーブル スキャンを実行します。
2. クエリを実行するときは、datetime フィールド タイプの値も引用符で囲む必要があります。そうしないと、MySQL は日付で処理しません。
3. 日付形式のデータの場合、varchar 型に設定すると、範囲クエリでインデックス クエリまたはフル テーブル スキャンを使用するための臨界値は、datetime 型クエリでインデックス クエリまたはフル テーブル スキャンを使用するための臨界値よりも低くなります。そのため、日付型データを datetime 型に設定すると、インデックス クエリが使用される可能性が高くなります。

MySQL が日付フィールド インデックスを使用しない理由に関するこの記事はこれで終わりです。MySQL 日付フィールド インデックスに関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • MySQLのどのフィールドがインデックスに適しているかについての簡単な説明
  • フィールドの文字セットの違いによる MySQL のインデックス失敗の解決策
  • MySQL のフィールドに一意のインデックスを追加および削除する方法
  • Mysqlはテーブルフィールドまたはインデックスが存在するかどうかを判断します

<<:  CSS スタイルで一般的なグラフィック効果を示すサンプルコード

>>:  入力ボックスのプレースホルダーテキストのデフォルトの色を変更する -webkit-input-placeholder メソッド

推薦する

JavaScriptでカレンダー効果を素早く実装

この記事では、カレンダー効果を素早く実現するためのJavaScriptの具体的なコードを例として紹介...

yum から docker インストール パッケージをダウンロードし、オフライン マシンにインストールする例の詳細なコード

1. ネットワークマシンでは、デフォルトのcentosyumソースを使用します [root@kole...

nginxアクセス制御の実装例

高性能で軽量なウェブサービスソフトウェアであるNginxについて高い安定性 システムリソースの消費量...

vue2 vue3 での Echarts の詳細な使用方法

目次1. インストール2. vue2でEchartsを使用するmain.jsファイル内コンテナが与え...

Dockerコンテナデータをコピーしてバックアップする方法の詳細な説明

ここでは、Jenkins コンテナを例に 3 つの方法を紹介します。方法1コンテナをイメージにパッケ...

デザインのヒント: きっと気に入っていただけると思います

<br />このタイトルを見ると、見覚えがあるかもしれません。多くのウェブサイトが同様の...

DockerにRabbitMQをインストールする詳細な手順

目次1. 鏡を見つける2. RabbitMQイメージをダウンロードする3. RabbitMQコンテナ...

Docker で FastDFS ファイル システムを構築する (マルチイメージ チュートリアル)

目次FastDFSについて1. 画像を検索する2. イメージをインストールする3.1. 必要なディレ...

JS 矢印関数に適さないシナリオは何ですか?

目次概要オブジェクトにメソッドを定義するオブジェクトリテラルオブジェクトプロトタイプ動的コンテキスト...

純粋な CSS カスタム複数行省略記号の問題 (原理から実装まで)

テキストオーバーフローを表示するにはどうすればいいですか? どのようなニーズがありますか?単一行です...

js で継承を実装する 5 つの方法

コンストラクタの借用この手法の基本的な考え方は単純です。サブタイプ コンストラクター内からスーパータ...

MySQL シリーズ: MySQL リレーショナル データベースの基本概念

目次1. 基本概念2. データベース管理技術の開発3. リレーショナルデータベース(RDBMS)の概...

CSS3でシャトル星空のアニメーションを実現

結果: html <canvas id="スターフィールド"><...

Vue 画像切り抜きコンポーネントのサンプルコード

例:ヒント:このコンポーネントはvue-cropperの二次パッケージに基づいていますプラグインをイ...

Linux 7.7 でスワップ パーティション SWAP を設定する方法

Linux システムの Swap パーティション、つまり swap パーティションは、一般に仮想メモ...