1

2 つの MySQL テーブルを結合してビューとして保存したいので、2 つのテーブルをクエリする代わりにアプリケーションでこのビューに対処できます。しかし、このビューはたまたま非常に遅いです。

これは私のテーブルです:

CREATE TABLE spectrumsets (
    setid INT(11) NOT NULL,
    timestampdt INT(11) NULL DEFAULT NULL,
    timestampd INT(10) UNSIGNED NOT NULL,
    timestampt INT(10) UNSIGNED NOT NULL,
    device INT(11) NOT NULL,
    methodname VARCHAR(50) NOT NULL,
    PRIMARY KEY (setid),
    UNIQUE INDEX setid_idx (setid),
    UNIQUE INDEX timestamp_device_idx (timestampd, timestampt, device),
    INDEX device_fk (device),
    INDEX timestampd_idx (timestampd),
    CONSTRAINT device_fk FOREIGN KEY (device)
        REFERENCES spectrumdevices (deviceid)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB

CREATE TABLE spectrumdata (
    valueid INT(11) NOT NULL AUTO_INCREMENT,
    spectrumset INT(11) NOT NULL,
    wavelength DOUBLE NULL DEFAULT NULL,
    intensity DOUBLE NULL DEFAULT NULL,
    PRIMARY KEY (valueid),
    INDEX spectrumset_idx (spectrumset),
    CONSTRAINT spectrumset_fk FOREIGN KEY (spectrumset)
        REFERENCES spectrumsets (setid)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB

そして、これは私の見解です:

SELECT spectrumsets.timestampd,spectrumsets.timestampt,spectrumsets.device,
    spectrumdata.wavelength,spectrumdata.intensity
FROM spectrumdata INNER JOIN spectrumsets ON spectrumdata.spectrumset=
    spectrumsets.setid
WHERE spectrumdata.wavelength>0 
ORDER BY spectrumsets.timestampd,spectrumsets.timestampt,spectrumsets.device,
    spectrumdata.wavelength

私のマシンの Aselect count(*)は 385.516 秒かかり、82923705 レコードになるため、かなり大きなデータセット

私はすでにこのリンクを見つけましたが、何が問題なのかまだ完全には理解していません。

アップデート:

EXPLAIN次の結果が得られます。

"id","select_type","table","type","possible_keys","key","key_len","ref","rows","Extra"
"1","SIMPLE","spectrumsets","index","PRIMARY,setid_idx","timestamp_device_idx","12",NULL,"327177","Using index; Using temporary; Using filesort"
"1","SIMPLE","spectrumdata","ref","spectrumset_idx","spectrumset_idx","4","primprod.spectrumsets.setid","130","Using where"
4

1 に答える 1

2

Explain は、クエリが結合のインデックスにヒットしている (これは良いことです) ことを示唆していますが、残りのクエリには一時テーブルとファイルの並べ替えを使用しています。

これには 2 つの理由があります。

  • where句がインデックスにヒットしていません
  • order by 句がインデックスにヒットしていません

コメントで、where 句を削除したことで大幅な改善が得られたとあなたは述べています。これは、波長に適切な数の可能な値があると仮定して、スペクトルセット、波長の複合インデックスが必要であることを示唆しています(値が10個だけの場合、インデックスは何もしない可能性があります)。

ビューから「order by」句を除外すると、はるかに高速になるはずです。また、ビューではなく、データを抽出するクエリによってソート順を決定できる場合もあります。私は、ほとんどのクエリがデータに関して非常に選択的であると推測しています - いくつかのタイムスタンプに制限されています。order by をビューに埋め込むことで、毎回ソートの代償を払うことになります。

ビューに "order by" がどうしても必要な場合は、"order by" の順序ですべてのフィールドを含むインデックスを作成し、先頭に結合します。例えば:

UNIQUE INDEX timestamp_device_idx (set_id、timestampd、timestampt、device)、

于 2012-05-10T13:54:22.387 に答える