web-dev-qa-db-ja.com

約5000万行のテーブルでMySQLのクエリを高速化する方法

テーブルには、datetime、smallint(6)、tinyint(4)、decimal(15,5)の4つの列があります。最初の3列はPKです。テーブルには4つのインデックスがあります。1つはすべてのPK列を持ち、もう1つは各列を個別に持ちます。テーブルには約5,000万行があり、急速に拡大します。計画では、最も古いデータをアーカイブすることにより、1億行未満に保ちます。さまざまな日時範囲とPK列の他の組み合わせに基づくレポートが頻繁に実行されますが、これらのレポートには時間がかかりすぎています。 10レコードを返すのに約5分。

列名

DateTimeStamp--DateTime ------ PK、NN

SystemNumber--SmallInt(6)------ PK、NN

DataNumber ------ TinyInt(4)------- PK、NN

値--------------- Decimal(15、5)

インデックス

Primary ------------------- BTREE-Unique --- DateTimeStamp、DataNumber、SystemNumber、value

DateTimeIDX ------------ BTREE-Non Unique--DateTimeStamp

DataNumber ------------- BTREE-Non Unique --- DataNumber

SystemNumberIDX ---- BTREE--Non Unique --- SystemNumber

Select  DateTimeStamp, Value
    From  SystemStats
    WHERE  DataType=16
      AND  DateTimeStamp >='" & StartDate & "'
      and  DateTimeStamp <= '" & EndDate & "'
      and  SystemNumber =" & mVars.SystemNumber & "
    Order by  DateTimeStamp;

私の質問


3
M.Gateley

_SHOW CREATE TABLE_を提供します。あなたが提供したものは不完全です。 5,000万行の4つのインデックスはINSERTsを遅くする可能性があります。それについて話し合う必要があります。

その1つのクエリには、1つの複合インデックスが必要です。

_(DataType, SystemNumber, DateTimeStamp) -- or
(SystemNumber, DataType, DateTimeStamp) -- (but not both)
_

順序は重要です。 「複合」インデックスは、各列のインデックスと同じではない。それらの1つは、おそらくあなたが言及したものではなく_PRIMARY KEY_である可能性があります(すべきです)。

最高のインデックスの作成に関する詳細な議論: http://mysql.rjweb.org/doc.php/index_cookbook_mysql

他のクエリがある場合。それらを見てみましょう。それ以外の場合は、残りのインデックスを削除します。

たぶん、あなたは「<=」ではなく「<」を意味しましたか? (BETWEENは包括的です。)

FLOATの代わりにDECIMAL(15,5)を使用する理由はありますか(これは4バイト(浮動小数点)で8を使用しますが、それでも6-7を意味します) 桁の精度。)

テーブルはInnoDBですか? PKが機能する方法のため、これは重要です。

あなたはPRIMARY KEY(DateTimeStamp, DataNumber, SystemNumber, value)を持っています;これは、date + num + sysの組み合わせごとに複数の値があることを期待しているという意味ですか(PKに「値」と呼ばれるものが含まれるのは珍しいことです。)

1
Rick James