編集1:
主キーをから変更するようです
PRIMARY KEY (`tm_stamp`,`fk_channel`)
に
PRIMARY KEY (`fk_channel`,`tm_stamp`)
MyISAMとInnoDBの両方にとって、常に意味があります。これが正しいことの証明については、 http://sqlfiddle.com/#!2/0aa08/1を参照してください。
元の答え:
変更するかどうかを判断するには
PRIMARY KEY (`tm_stamp`,`fk_channel`)
に
PRIMARY KEY (`fk_channel`,`tm_stamp`)
クエリのパフォーマンスを向上させるには、どのフィールドの値のカーディナリティが高いか(どのフィールドの値がより多様であるか)を判断する必要があります。ランニング
SELECT COUNT(DISTINCT tm_stamp), COUNT(DISTINCT fk_channel) FROM measurements;
列のカーディナリティが得られます。
それで、あなたの質問に正しく答えるために、私たちは最初に知る必要があります:との間の値の一般的な範囲は何B
ですかC
?60?3,600?86,400?もっと?
たとえば、
SELECT COUNT(DISTINCT tm_stamp), COUNT(DISTINCT fk_channel) FROM measurements;
32,768と256を返します。32,768を256で割ると128になります。これはtm_stamp
、の値ごとに128の一意の値があることを示していますfk_channel
。
B
したがって、との差C
が通常128未満の場合tm_stamp
は、主キーの最初のフィールドとして残します。128以上の場合はfk_channel
、最初のフィールドを作成します。
別の質問:(40億の一意の値、その半分は負の値)であるfk_channel
必要がありますか?INT
そうでない場合は、(256個の一意の値がある場合)または(65536個の一意の値)に変更fk_channel
すると、時間とスペースを大幅に節約できます。TINYINT UNSIGNED
SMALLINT UNSIGNED
たとえば、256の可能な最大fk_channel
値と65,536の可能な値があるとするとvalue
、次の方法でスキーマを変更できます。
create table measurements_new (
tm_stamp INT UNSIGNED NOT NULL DEFAULT '0',
fk_channel TINYINT UNSIGNED NOT NULL DEFAULT '0', -- remove UNSIGNED if values can be negative
value SMALLINT UNSIGNED DEFAULT NULL, -- remove UNSIGNED if values can be negative
PRIMARY KEY (tm_stamp,fk_channel)
) ENGINE=InnoDB
SELECT
tm_stamp,
fk_channel,
value
FROM
measurements
ORDER BY
tm_stamp,
fk_channel;
RENAME TABLE measurements TO measurements_old, measurements_new TO measurements;
これにより、既存のデータが新しいテーブルにPRIMARY KEY
順番に格納され、パフォーマンスがいくらか向上します。