SELECT * FROM Table
VSのパフォーマンスペナルティSELECT * FROM (SELECT * FROM Table AS A) AS B
パフォーマンスペナルティが
は何私の質問があるの照会しますWHERE句が指定されていないため)、WHERE句はWHERE句が指定されていないので、WHERE句はWHERE句を使用しないため、2回繰り返す必要があります。ありがとう...
SELECT * FROM Table
VSのパフォーマンスペナルティSELECT * FROM (SELECT * FROM Table AS A) AS B
パフォーマンスペナルティが
は何私の質問があるの照会しますWHERE句が指定されていないため)、WHERE句はWHERE句が指定されていないので、WHERE句はWHERE句を使用しないため、2回繰り返す必要があります。ありがとう...
この質問に対する答えは、5.7または5.7より前にmysqlを使用しているかどうかによって決まります。私はあなたの質問を少し変えているかもしれませんが、うまくいけば、あなたが後にしていることを以下のように捕捉してください。
SELECT * FROM Table
は、クラスタ化インデックス(物理的な順序付け)を介してテーブルスキャンを実行します。主キーがない場合は、implicitlyがエンジンで使用可能です。あなたが言うようにwhere節はありません。他の索引のフィルタリングまたは選択は試行されません。
出力(alsoを参照)は、その要約に1行を示します。Explain出力これは比較的単純です。派生テーブルB
による説明出力とパフォーマンスは、5.7より前のバージョンか5.7より前のバージョンかによって異なります。
ドキュメントDerived Tables in MySQL 5.7は、外部クエリに組み込まれているマテリアライズド・テーブル出力が変更されたため、後者ではペナルティが発生しません。以前のバージョンでは、派生した一時テーブルを使用してかなりのオーバーヘッドが発生しました。
5.7より前のパフォーマンスペナルティをテストするのは簡単です。あなたの質問の派生テーブルがパフォーマンスに影響を与えているという顕著な影響を見るためには、中程度のサイズのテーブルが必要です。次の例は、バージョン5.6に小さなテーブルの上にある:
explain
select qm1.title
from questions_mysql qm1
join questions_mysql qm2
on qm2.qid<qm1.qid
where qm1.qid>3333 and qm1.status='O';
+----+-------------+-------+-------+-----------------+---------+---------+------+-------+------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+-----------------+---------+---------+------+-------+------------------------------------------------+
| 1 | SIMPLE | qm1 | range | PRIMARY,cactus1 | PRIMARY | 4 | NULL | 5441 | Using where |
| 1 | SIMPLE | qm2 | ALL | PRIMARY,cactus1 | NULL | NULL | NULL | 10882 | Range checked for each record (index map: 0x3) |
+----+-------------+-------+-------+-----------------+---------+---------+------+-------+------------------------------------------------+
explain
select b.title from
( select qid,title from questions_mysql where qid>3333 and status='O'
) b
join questions_mysql qm2
on qm2.qid<b.qid;
+----+-------------+-----------------+-------+-----------------+---------+---------+------+-------+----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------------+-------+-----------------+---------+---------+------+-------+----------------------------------------------------+
| 1 | PRIMARY | qm2 | index | PRIMARY,cactus1 | cactus1 | 10 | NULL | 10882 | Using index |
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 5441 | Using where; Using join buffer (Block Nested Loop) |
| 2 | DERIVED | questions_mysql | range | PRIMARY,cactus1 | PRIMARY | 4 | NULL | 5441 | Using where |
+----+-------------+-----------------+-------+-----------------+---------+---------+------+-------+----------------------------------------------------+
注、私は質問を変更しましたが、それは表の派生影響を示し、オプティマイザでインデックスの使用の欠如は、前5.7へのバージョンにあり。派生テーブルは、索引がマテリアライズされているときに索引を利用します。しかしその後、一時的なテーブルとしてオーバーヘッドを費やし、インデックスを使用せずに外部クエリに組み込みます。これはバージョン5.7のケースではありません
説明: –
パフォーマンスの問題について、2つのサブクエリ間の結合操作では、外部クエリではなく内部クエリでLIMIT句を指定することをお勧めしますか? '((SELECT id FROM Table1)NATURAL JOIN表2))LIMIT 10'(これはいくつかの構文エラーを含んでいる可能性があります。テーブル命名との関係ですが...)?ありがとう:) –
あなたのサーバーのバージョン、あなたのスキーマでそれを再生することをお勧めします。以下は、サーバー以外のラップトップ上の[5.6](http://i.imgur.com/jxsrvB2.jpg)です。自然な結合は使用しません。私は幅広い筆のストロークの回答をしないようにします。特に、同じように見えるかもしれない 'Explain'の出力に。それはスタック上であまりにも多く発生します。代わりに、より大きなデータセットでクエリを指し示し、最悪の実行クエリや[ここ](http://stackoverflow.com/a/38189113)などの一般的な調査で少なくとも15分のテストを実行します。パフォーマンスはオプティマイザに基づいてバージョンによって異なります。 – Drew