過去 2 日間で、完全なテーブル スキャンを引き起こす可能性のある 2 種類の SQL を確認しました。落とし穴を避けるために、次の 2 つの例をご覧ください。 ケース1:強制型変換の場合、インデックスは使用されず、テーブル全体のスキャンが実行されます。 以下にいくつか例を挙げます。 まずテーブルを作成します テーブル「test」を作成します( `id` int(11) NOT NULL AUTO_INCREMENT, `age` int(11) デフォルト NULL, `score` varchar(20) NOT NULL DEFAULT '', 主キー (`id`)、 キー `idx_score` (`score`) ) エンジン=InnoDB AUTO_INCREMENT=12 デフォルト文字セット=utf8 このテーブルには 3 つのフィールドがあり、そのうち 2 つは int 型で 1 つは varchar 型であることがわかります。 varchar 型フィールドのスコアはインデックスであり、id は主キーです。 次に、このテーブルにデータを挿入します。データ挿入後のテーブルは次のようになります。 mysql:yeyztest 21:43:12>>テストから*を選択します。 +----+------+-------+ | ID | 年齢 | スコア | +----+------+-------+ | 1 | 1 | 5 | | 2 | 2 | 10 | | 5 | 5 | 25 | | 8 | 8 | 40 | | 9 | 2 | 45 | | 10 | 5 | 50 | | 11 | 8 | 55 | +----+------+-------+ セット内の行数は 7 です (0.00 秒) この時点で、explain ステートメントを使用して、次の 2 つの SQL ステートメントの実行を表示します。 スコアが '10' であるテストから * を選択します。 スコア =10 のテストから * を選択します。 結果は次のとおりです。 mysql:yeyztest 21:42:29>>スコア='10'; でテストから * を選択します。 +----+-------------+---------+-----------+--------+---------------+------------+-------+-------+------+------+------+------+ | id | select_type | テーブル | パーティション | タイプ | 可能なキー | キー | キー長 | ref | 行 | フィルター済み | 追加 | +----+-------------+---------+-----------+--------+---------------+------------+-------+-------+------+------+------+------+ | 1 | SIMPLE | テスト | NULL | ref | idx_score | idx_score | 62 | const | 1 | 100.00 | NULL | +----+-------------+---------+-----------+--------+---------------+------------+-------+-------+------+------+------+------+ セットに 1 行、警告 1 件 (0.00 秒) mysql:yeyztest 21:43:06>>スコア=10のテストからselect *を説明します。 +----+-------------+--------+-----------+--------+---------------+-------+--------+----------+-----------+-------------+ | id | select_type | テーブル | パーティション | タイプ | 可能なキー | キー | キー長 | ref | 行 | フィルター済み | 追加 | +----+-------------+--------+-----------+--------+---------------+-------+--------+----------+-----------+-------------+ | 1 | SIMPLE | テスト | NULL | ALL | idx_score | NULL | NULL | NULL | 7 | 14.29 | where の使用 | +----+-------------+--------+-----------+--------+---------------+-------+--------+----------+-----------+-------------+ セットに 1 行、警告 3 件 (0.00 秒) varchar 型の値を使用すると、結果でスキャンされる行数は 1 であり、整数値 10 を使用すると、スキャンされる行数は 7 になることがわかります。これは、強制的な型変換が発生すると、インデックスが無効になることを示しています。 ケース2:逆クエリではインデックスを使用できないため、テーブル全体のスキャンが行われます。 主キーが score であるテーブル test1 を作成し、6 つのレコードを挿入します。 テーブル「test1」を作成します( `score` varchar(20) NULLでないデフォルト '' , 主キー (`score`) ) エンジン=InnoDB デフォルト文字セット=utf8 mysql:yeyztest 22:09:37>>test1から*を選択します。 +-------+ | スコア | +-------+ | 111 | | 222 | | 333 | | 444 | | 555 | | 666 | +-------+ セット内の 6 行 (0.00 秒) 逆引き検索を使用する場合、インデックスは使用されません。次の 2 つの SQL ステートメントを見てみましょう。 select * from test1 where score='111'; を説明します。 select * from test1 where score!='111'; を説明します。 mysql:yeyztest 22:13:01>>スコア='111'; で test1 から select * を実行します。 +----+-------------+---------+-----------+---------+---------------+---------+--------+----------+-----------+-------------+ | id | select_type | テーブル | パーティション | タイプ | 可能なキー | キー | キー長 | ref | 行 | フィルター済み | 追加 | +----+-------------+---------+-----------+---------+---------------+---------+--------+----------+-----------+-------------+ | 1 | SIMPLE | test1 | NULL | const | PRIMARY | PRIMARY | 62 | const | 1 | 100.00 | インデックスを使用 | +----+-------------+---------+-----------+---------+---------------+---------+--------+----------+-----------+-------------+ セットに 1 行、警告 1 件 (0.00 秒) mysql:yeyztest 22:13:08>>explain select * from test1 where score!='111'; +----+-------------+--------+-----------+---------+---------------+---------+-------+-------+----------+----------------------------+ | id | select_type | テーブル | パーティション | タイプ | 可能なキー | キー | キー長 | ref | 行 | フィルター済み | 追加 | +----+-------------+--------+-----------+---------+---------------+---------+-------+-------+----------+----------------------------+ | 1 | SIMPLE | test1 | NULL | index | PRIMARY | PRIMARY | 62 | NULL | 6 | 100.00 | where の使用; index の使用 | +----+-------------+--------+-----------+---------+---------------+---------+-------+-------+----------+----------------------------+ セットに 1 行、警告 1 件 (0.00 秒) 見ればわかります、使ってみてください! = 条件として使用する場合、スキャンされる行数はテーブル内の行の合計数になります。したがって、インデックスを使用する場合は、逆一致ルールは使用できません。 ケース3:特定の条件または値条件により、テーブル全体のスキャンが実行される場合があります。 まずテーブルを作成し、データを挿入します。 テーブル「test4」を作成します( `id` int(11) デフォルト NULL, `name` varchar(20) デフォルト NULL, キー `idx_id` (`id`) ) エンジン=InnoDB デフォルト文字セット=utf8 セット内の 1 行 (0.00 秒) [email protected]:yeyztest 22:23:44>>test4 から * を選択します。 +------+------+ | ID | 名前 | +------+------+ | 1 | ああ | | 2 | bbb | | 3 | ccc | | 4 | うんざり | | NULL | ええと | +------+------+ セット内の行数は 5 です (0.00 秒) テーブル test4 には 2 つのフィールドがあります。id フィールドはインデックスで、name フィールドは varchar 型です。次の 3 つのステートメントでスキャンされた行の数を見てみましょう。 select * from test4 where id=1; を説明します。 id が null である test4 から * を選択します。 select * from test4 where id=1 or id is null; を説明します。 mysql:yeyztest 22:24:12>>idがnullの場合にtest4から*を選択することを説明します。 +----+-------------+--------+-----------+--------+---------------+---------+-------+--------+---------+------------------------+ | id | select_type | テーブル | パーティション | タイプ | 可能なキー | キー | キー長 | ref | 行 | フィルター済み | 追加 | +----+-------------+--------+-----------+--------+---------------+---------+-------+--------+---------+------------------------+ | 1 | SIMPLE | test4 | NULL | ref | idx_id | idx_id | 5 | const | 1 | 100.00 | インデックス条件を使用 | +----+-------------+--------+-----------+--------+---------------+---------+-------+--------+---------+------------------------+ セットに 1 行、警告 1 件 (0.00 秒) mysql:yeyztest 22:24:17>>select * from test4 where id=1; の説明 +----+-------------+--------+-----------+--------+---------------+---------+-------+-------+------+------+------+ | id | select_type | テーブル | パーティション | タイプ | 可能なキー | キー | キー長 | ref | 行 | フィルター済み | 追加 | +----+-------------+--------+-----------+--------+---------------+---------+-------+-------+------+------+------+ | 1 | SIMPLE | test4 | NULL | ref | idx_id | idx_id | 5 | const | 1 | 100.00 | NULL | +----+-------------+--------+-----------+--------+---------------+---------+-------+-------+------+------+------+ セットに 1 行、警告 1 件 (0.00 秒) mysql:yeyztest 22:24:28>>explain select * from test4 where id=1 or id is null; +----+-------------+--------+-----------+--------+---------------+-------+--------+----------+-----------+-------------+ | id | select_type | テーブル | パーティション | タイプ | 可能なキー | キー | キー長 | ref | 行 | フィルター済み | 追加 | +----+-------------+--------+-----------+--------+---------------+-------+--------+----------+-----------+-------------+ | 1 | SIMPLE | test4 | NULL | ALL | idx_id | NULL | NULL | NULL | 5 | 40.00 | where の使用 | +----+-------------+--------+-----------+--------+---------------+-------+--------+----------+-----------+-------------+ セットに 1 行、警告 1 件 (0.00 秒) id=1 と id is null のみを使用すると、レコードの 1 行のみがスキャンされますが、 または を使用して 2 つを接続すると、インデックスを使用せずにテーブル全体がスキャンされることがわかります。 簡単にまとめると:1. 強制型変換の場合、インデックスは使用されず、テーブル全体のスキャンが実行されます。 2. 逆クエリではインデックスを使用できないため、テーブル全体がスキャンされます。 3. 一部の条件または値条件により、テーブル全体のスキャンが実行される場合があります。 上記は、MySQL がフル テーブル スキャンを実行するいくつかの状況の詳細です。MySQL フル テーブル スキャンの詳細については、123WORDPRESS.COM の他の関連記事をご覧ください。 以下もご興味があるかもしれません:
|
mysqlslap共通パラメータの説明–auto-generate-sql システムはテスト用のSQ...
Mysql の追加、削除、変更、クエリステートメントのシンプルな実装追加されたレコード: テーブル名...
Centos や Ubuntu など、Docker が pull する Base イメージは最もシン...
目次マウスジョイント マウスジョイント距離ジョイント距離ジョイントモータージョイント直動ジョイント変...
質問通常の開発では、プロジェクトを Tomcat にデプロイする場合、プロジェクトを war パッケ...
CSS 3.0 とビデオを組み合わせて実現したクリエイティブなオープニングをご紹介します。効果は次の...
拡張版です。質問とSQL文は以下の通りです。ユーザー テーブルを作成し、id、name、gender...
すべてのデータベースの合計サイズを照会する方法は次のとおりです。 mysql> informa...
導入js コード文の末尾にセミコロンを追加しても追加しなくても問題ありません。一般的に、チームで開発...
目次非同期とは何ですか?なぜ非同期性が必要なのでしょうか?非同期IOとは何ですか?イベントループとは...
この記事では、オンラインリアルタイム多人数チャットルームを実現するためのNode.js+expres...
目次1. データベースのマスター/スレーブ分類: 2. MySQL マスタースレーブの紹介3. マス...
先日、外国人の方がHTML+CSSを使ってHamburgerMenuを実装している動画を見ました。最...
a タグが新しいページを開くかどうか: (1)百度百科事典:ヘッダーが異なる場合は新しいページが開き...
1. リポジトリファイルを作成するmongodb の公式インストール ドキュメントを参照し、次のスク...