1

2つのテーブルt1->t2(一般的な1対多の関係)があり、テーブルt2に140.000レコードがあり、t1に50.000レコードがあり、外部キーがnull(親なし)になることがあります。

CREATE TABLE `t1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`),
KEY `name_idx` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=125666 DEFAULT CHARSET=utf8

CREATE TABLE `t2` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`t1_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `t1_id_idx` (`t1_id`)
CONSTRAINT `t1_fk` FOREIGN KEY (`t1_id`) REFERENCES `t1` (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=125666 DEFAULT CHARSET=utf8

このクエリは15秒で実行されます:

SELECT * FROM t2
LEFT JOIN t1 ON t2.t1_id = t1.id
ORDER BY t1.name ASC
LIMIT 10; 

このクエリは0.5秒で実行されます:

SELECT * FROM t2
LEFT JOIN t1 ON t2.t1_id = t1.id
WHERE t1.name <> 'any not found value'
ORDER BY t1.name ASC
LIMIT 10;

なぜこれが起こるのか、誰かが私に説明できますか?

Obs:編集済み。

ニュース:

このクエリは0.06秒で実行されます:(何が変更されましたか?内部結合!!)

SELECT * FROM t2
INNER JOIN t1 ON t2.t1_id = t1.id
ORDER BY t1.name ASC
LIMIT 10; 

しかし、上記のクエリは私の解決策ではありません。私の場合、t2.t1_idがnullになることがあります。

何か案が??

ニュース:

左結合と内部結合でexplainを実行します。

Mysql show:一時的なものを使用します。filesortの使用; 行:140.000

内部結合あり:

Mysql show:Whereの使用; 行:8

4

2 に答える 2

2

解決しました!

問題は順序どおりです。orderbymysqlを使用して一時ファイルを作成すると(説明...一時ファイルを使用)、この一時ファイルが大きすぎて遅延が発生します。

チップ:

  • Tempoarayの使用は避けてください
  • 一時を使用する場合は、多くのデータをロードしないでください。
于 2012-06-15T12:43:53.917 に答える
0

すでにインデックスが付いていると思いますが、t1.name昇順ではなく降順です。これが、2番目のクエリが非常に高速である理由を説明しています。

もう1つの説明は、最初のクエリはキャッシュされなかったが、2番目のクエリはキャッシュ内のデータを検出し、より高速に実行されたというものです。

于 2012-06-06T18:00:06.873 に答える