MySQLサーバをバージョン5.7(Ubuntu 16.04 LTSの下で)にアップデートしたときに、私はいくつかの奇妙な問題が発生しました。パーティションテーブルのASC/DESCによるMySQL 5.7の異常なパフォーマンスの低下
Preambula:私は、たくさんのレコード(〜250万)を持つテーブルを持っています。
CREATE TABLE `device_data` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`device` int(11) DEFAULT NULL,
`data` double NOT NULL DEFAULT '0',
`utc` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`utc`,`id`),
KEY `id` (`id`),
KEY `idx_devutc` (`device`,`utc`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE (`utc`)
(PARTITION y_min VALUES LESS THAN (1200000000) ENGINE = MyISAM,
PARTITION y_121 VALUES LESS THAN (1210000000) ENGINE = MyISAM,
PARTITION y_122 VALUES LESS THAN (1220000000) ENGINE = MyISAM,
...
...
...
PARTITION y_167 VALUES LESS THAN (1670000000) ENGINE = MyISAM,
PARTITION y_168 VALUES LESS THAN (1680000000) ENGINE = MyISAM,
PARTITION y_169 VALUES LESS THAN (1690000000) ENGINE = MyISAM,
PARTITION y_max VALUES LESS THAN MAXVALUE ENGINE = MyISAM) */
が、なぜそのような異例のプライマリキー(UTC、ID)を持っているん:この表は、短期では、このような構造を持っていますか?フィールドIDは自動インクリメントで、それに沿ってプライマリキーにすることができます。 UTCフィールドでテーブルを分割する必要があります。そのためには、フィールドUTCは主キーまたは少なくとも主キーの最初の部分でなければなりません。デバイスはプライマリキーとしてUTCを使用することはできません。デバイスは1秒に何回もデータを送信できるため、このような奇妙なプライマリキー(UTC、ID)を使用する必要があります。これで結構です。
また、このテーブルには(device、utc)というインデックスがあります。どうして?我々は
SELECT `utc`, `data`
FROM `device_data`
WHERE `device` = :DeviceId AND `utc` >= :UtcFrom AND `utc` < :UtcTo
ORDER BY `utc`;
:、一定時間、特定のデバイスによって例えばデータを取得するクエリを実行する必要があるので、それは理由指数(デバイス、UTC)の非常に高速です。
Ambula:MySQL Serverをバージョン5.7(バージョン5.0または5.1からアップグレードした後は、わからない)で、一部のクエリが非常に遅くなります(100〜200ミリ秒の代わりに2〜3分)。いくつかの小さな調査では、ソートの順序が子孫であるときにクエリ速度が低下するという条件が見つかっています。 (〜180秒)
SELECT `utc`, `data`
FROM `device_data`
WHERE `device` = :DeviceId AND `utc` >= :UtcFrom AND `utc` < :UtcTo
ORDER BY `utc` ASC;
しかし、このクエリは非常に遅いです:同じのparam値で
SELECT `utc`, `data`
FROM `device_data`
WHERE `device` = :DeviceId AND `utc` >= :UtcFrom AND `utc` < :UtcTo
ORDER BY `utc` DESC;
、当然の
このクエリは、まだ(100 milllseconds)高速です。 以前のバージョンのMySQL Serverでは、両方のクエリが高速でした(100〜200ミリ秒)。
は、このクエリも高速で、ミリ秒単位で仕上げている
SELECT `utc`, `data`
FROM `device_data`
WHERE `device` = :DeviceId AND `utc` >= :UtcFrom AND `utc` < :UtcTo
ORDER BY -`utc` ASC;
(BY ORDERでutc
の前にマイナス記号のAttantion):
は懸命に仕事の2日後、私はこの問題を回避するために、いくつかのトリックを発見しました必要に応じて逆の順序でレコードを返します。
しかし、問題は次のとおりです。
質問:どのように奇妙なMySQLの行動の理由で、どのように私はそれを修正することができますか?
ご意見はありますか?
ありがとうございました。
slowクエリとfastクエリでどのインデックスがどのインデックスで使用されているかをplsで調べることはできますか? – Shadow
驚きはありません。両方ともidx_devutcを使用してください。さらに、 'FORCE INDEX(idx_devutc)'修飾子を使用した同じクエリは同じ結果を示します。 – tumick
余分なセクションにファイルがありませんか? – Shadow