1

MySQL 5.5 DB で次の問題が発生しました。

2 つのテーブル:


表1

CREATE TABLE `sequence_matches` (
    `Sample_ID` INT(6) NOT NULL,
    `Sequence_Match_ID` INT(8) NOT NULL,
    `Start` INT(6) NULL DEFAULT NULL,
    `End` INT(6) NULL DEFAULT NULL,
    `Coverage` DOUBLE(5,2) NULL DEFAULT NULL,
    `Frag_String` VARCHAR(255) NULL DEFAULT NULL,
    `rms_mass_error_prod` DOUBLE(10,4) NULL DEFAULT NULL,
    `rms_rt_error_prod` DOUBLE(10,4) NULL DEFAULT NULL,
  PRIMARY KEY (`Sample_ID`, `Sequence_Match_ID`)
)


表 2

CREATE TABLE `peptide_identifications` (
   `Sample_ID` INT(6) NOT NULL,
   `Peptide_identification_ID` INT(8) NOT NULL,
   `Mass_error` DOUBLE(10,4) NULL DEFAULT NULL,
   `Mass_error_ppm` DOUBLE(10,4) NULL DEFAULT NULL,
   `Score` DOUBLE(10,4) NULL DEFAULT NULL,
   `Type` VARCHAR(45) NULL DEFAULT NULL,
   `global_pept_ID` INT(8) NOT NULL,
  PRIMARY KEY (`Sample_ID`, `Peptide_identification_ID`),
  INDEX `Index` (`global_pept_ID`)
)

それぞれに約 1,500 万行が含まれています。

Table2ここで、 whereからすべての行を取得し、それらglobal_pept_id = 27443の を使用して、wherepeptide_identification_idからすべての情報を照会します。Table1peptide_identification_id = sequence_match_id

次のステートメントを試しました。

SELECT * from sequence_matches 
JOIN (
  SELECT peptide_identification_id 
  FROM peptide_identifications 
  WHERE global_pept_id = 27443
) as tmp_pept 
ON sequence_match_id = peptide_identification_id; 

そのクエリの説明は次のとおりです。

http://i.stack.imgur.com/QV3ER.jpg(拡大するにはクリックしてください)

これで、このクエリは非常に遅くなり (実際には終了せず、約 10 分後に停止しました)、2 番目のテーブルに使用されるインデックスがないためだと想像できますが、両方の ID は主キーであるため、正しくインデックスを作成する必要があります。

単独で実行した場合、内部選択の結果には最大 3 秒かかり、最大 3,000 行が返されます。したがって、問題は 3000 * 15mio の比較を行っているため、Table2 ですべての行がチェックされていると思います。

しかし、どうすればこれを修正できますか?

助けていただければ幸いです-void

4

4 に答える 4

4

おそらく、サブクエリに参加しているためです。試す:

SELECT sm.*, pi.peptide_identification_id
FROM sequence_matches sm
INNER JOIN peptide_identifications pi
ON sm.id = pi.peptide_identification_id
WHERE pi.global_pept_id = 27443
于 2013-01-29T12:36:36.427 に答える
1

他のソリューションとは少し異なります。最初に取得しようとしている主要な基準を考えてみましょう...特定のグローバルペプチド値のペプチド要素です。クエリを実行する可能性のある基準 (所有している基準) について、このテーブルにインデックスがあることを確認してください。ただし、同じテーブルに対して複数の WHERE 条件でクエリを実行することがわかった場合は、両方の条件に役立つインデックスを準備/作成してみてください。

次に、PK/FK 関係の他のテーブルに JOIN 条件を配置して、それらのレコードを取得します。

SELECT * 
   from 
      peptide_identification PI
         JOIN sequence_matches SM
            ON PI.peptide_identification_id = SM.sequence_match_id
   WHERE 
      PI.global_pept_id = 27443

適切なインデックスがないと、クエリのパフォーマンスが大幅に低下する可能性があります。Sequence_Matches テーブルには、最適化を支援するために (Sequence_match_ID) だけにインデックスが必要です。2 番目の位置 (sample_id の後) に配置しても、期待どおりのメリットはありません。

于 2013-01-29T12:49:53.293 に答える
0

ヒントは、サブセレクトを避けることです。時には素晴らしいこともありますが、通常はパフォーマンスが低下します。より良い方法は次のとおりです。

SELECT * from peptide_identification as tmp_pept
JOIN sequence_matches  
    ON sequence_matches.sequence_match_id = tmp_pept.peptide_identification_id
WHERE tmp_pept.global_pept_id = 27443

それはトリックを行いますか?

編集: いいえ、本当の問題は、sequence_match_id にインデックスがないことです。1つ追加すれば、おそらく大丈夫です。

于 2013-01-29T12:36:05.080 に答える
0

内部結合ではなくクロス結合を作成しているため、問題が発生する可能性があると思います。サブクエリは、1500 万行 * 300 万行のデカルト積を作成しています。

内部結合を使用すると、その数を 1500 万 * 3000 行に減らすことができます。

それはまだ膨大な数です。Sql の最後で、TOP 10 または TOP 20 を発行することで制限できます。

フロント エンドでは、C# の場合、グリッドビュー ページャーなどのページング手法を使用するか、データ ソースで他のページング手法を使用する必要があります。これは、SQL 結合クエリとページ 20 の結果の上に配置される結果をフロント エンドに表示することを前提としています。時間。

于 2013-01-29T12:39:27.460 に答える