(この回答はスキーマとSELECTに向けられています。)
何百万もの行が予想されるので、最初にスキーマのいくつかの改善点を指摘したいと思います。
-
FLOAT(m,n)
これは通常、2つの丸めにつながるため、「間違った」ことです。プレーンなFLOAT
を使用する (電圧などの指標には「正しい」ようです)またはDECIMAL(m,n)
を使用します 。FLOAT
4バイトです。与えられた場合、DECIMAL
3バイトまたは4バイトになります。 -
両方の
INDEX(a)
がある場合 およびINDEX(a,b)
、後者はそのようなことをカバーできるので、前者は不要です。不要なキーが3つあります。これにより、INSERTs
の速度が低下します 。 -
INT(3)
-「3桁の数字」って言ってるの?その場合は、TINYINT UNSIGNED
を検討してください。 (値0..255)INT
の代わりに1バイト 4バイトの場合。これにより、多くのMBのディスク容量が節約されるため、速度が向上します。 (SMALLINT
も参照してください 、など、およびSIGNED
またはUNSIGNED
。) -
filename
の場合 何度も繰り返される場合は、「正規化」することをお勧めします。これにより、多くのMBを節約できます。 -
NOT NULL
を使用するNULL
が必要な場合を除きます 何かのために。 -
AUTO_INCREMENT=690892041
id
で災害への道の約1/3であることを意味します 、これは約20億で最高になります。id
を使用していますか 何かのために?列を削除すると、問題を回避できます。UNIQUE KEY
を変更しますPRIMARY KEY
へ 。 (id
が必要な場合 、さらに話しましょう。) -
ENGINE=MyISAM
-切り替えには、有利な場合と不利な場合の両方の影響があります。テーブルは2〜3倍の大きさになります。PRIMARY KEY
の「正しい」選択 これをさらにスピードアップしますSELECT
大幅。 (そして、他のSELECTs
を遅くする場合と遅くしない場合があります 。)
SELECT
に関するメモ :string
以降 およびunit_num
はクエリの定数であり、ORDER BY timestamp asc, string asc, unit_num asc
の最後の2つのフィールドです。 不要です。 SELECT
では明らかでない理由で関連性がある場合 、その後、私のアドバイスは不完全かもしれません。
これ
WHERE filename = 'foobar'
AND unit_num='40'
AND string='2'
AND timestamp >= ...
INDEX(filename, unit_name, string, timestamp)
によって最適に処理されます 。列の順序は重要ではありません そのtimestamp
最後である必要があります 。現在のUNIQUE
を再配置する キー、あなたはあなたに最適なインデックスを与えます。 (一方、このSELECT
に適したインデックスはありません。 。)PRIMARY KEY
にする テーブルInnoDBを使用すると、さらに高速になります。
パーティショニング?利点はありません。パフォーマンスのためではありません。あなたが言及した他の何のためでもありません。パーティショニングの一般的な使用法は、「古い」をパージすることです。そのようなことをするつもりなら、さらに話しましょう。
巨大なテーブルでは、すべての重要なSELECTs
を確認するのが最適です。 同時に、他の人の速度を破壊しながら1人の速度を上げないようにします。 かもしれません パーティショニングがこの種のトレードオフに役立つことさえわかっています。