2016-08-18 10 views
5

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の行動の理由で、どのように私はそれを修正することができますか?

ご意見はありますか?

ありがとうございました。

+0

slowクエリとfastクエリでどのインデックスがどのインデックスで使用されているかをplsで調べることはできますか? – Shadow

+0

驚きはありません。両方ともidx_devutcを使用してください。さらに、 'FORCE INDEX(idx_devutc)'修飾子を使用した同じクエリは同じ結果を示します。 – tumick

+0

余分なセクションにファイルがありませんか? – Shadow

答えて

3

私はMySQLの開発者ではありませんので、詳細はわかりません。

しかし、battled this on their issue trackerを持った後、最良の推測はそれがthis fix added in 5.7.3によって引き起こさ回帰であるということです。

パーティション:インデックス条件のプッシュダウンは、分割されたテーブルでは動作しませんでした。 (バグ#17306882、バグ#70001)この理論は、我々がmy.cnfでこれを設定することで問題を回避することができましたという事実によって強調されている

optimizer_switch=index_condition_pushdown=off

ひとつはなく、これを試すことができますを使用して再起動します。

また、ORDER BY -`utc` ASCのアプローチも見ていましたが、それぞれの実行計画にUsing filesortが追加されているので、怖がっていました。

関連する問題