0

300 000レコードのテーブルがあります(MyISAM)。この関数を使用して、このテーブルからレコードを取得します。

public function loadRows() {
    if (!$this->result)
        die("Nothing found!");
    $this->rows = array();
    while ($r = mysql_fetch_array($this->result, MYSQL_ASSOC))
        $this->rows[] = $r;
    //mysql_free_result($this->result);
    return $this->rows;
}

このテーブルから100レコードを表示するための推定時間は6秒で、非常に遅く、このクエリで使用されるMEMORYは512MBです。どこが間違っているの?

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

SELECT i.* FROM inv i 
LEFT JOIN (inv_m im) ON (i.m_id = im.id)
LEFT JOIN (inv_f iff) ON (iff.num = i.num)
LEFT JOIN (temp_a ta) ON (ta.num = i.num)
WHERE i.vid = 1
AND iff.num IS NULL
AND ta.num IS NULL
LIMIT 100

i.vidの場合、すべてのレコードを表示します。

宣言されたインデックス:

i.m_id INDEX

im.id主キー

iff.num INDEX

i.num INDEX

ta.num INDeX

説明の結果

id  select_type  table  type     possible_keys  key      key_len  ref                 rows    Extra
1   SIMPLE       i      ref      vid            vid      4        const               85343   Using where
1   SIMPLE       im     eq_ref   PRIMARY        PRIMARY  4        checksys_r1.i.m_id  1 
1   SIMPLE       iff    ref      num            num      182      checksys_r1.i.num   1       Using where
1   SIMPLE       ta     ref      num            num      194      checksys_r1.i.num   1       Using where
4

2 に答える 2

1

実行することから始めます:

EXPLAIN SELECT i.* FROM inv i 
LEFT JOIN (inv_m im) ON (i.m_id = im.id)
LEFT JOIN (inv_f iff) ON (iff.num = i.num)
LEFT JOIN (temp_a ta) ON (ta.num = i.num)
WHERE i.vid = 1
AND iff.num IS NULL
AND ta.num IS NULL
LIMIT 100

全行スキャン、ファイル I/O などを探します。結果をここに投稿してください。テーブルの修理が必要な場合もあります。

また、InnoDB で MyISAM を使用している理由はありますか?

于 2012-06-20T12:34:18.420 に答える
-1

考えられる原因は 2 つありますが、どちらもおそらく寄与しています。まず、可能な限り * を選択しないようにしてください。列を明示的に指定すると、マスター データベースに対する結合クエリごとに、列名を何度も検索する手間が省けます。2 つ目は、結合後にのみ実行される where 句を指定していることです。したがって、すべての結合を含む大規模なレコードセットを作成し、後でそのレコード セットをフィルター処理します。条件を結合自体に移動すると、パフォーマンスがさらに向上するはずです。そう.....

SELECT i.Column1, i.Column2, i.Column3 
FROM inv i 
LEFT JOIN (inv_m im) ON (i.m_id = im.id AND i.vid = 1)
LEFT JOIN (inv_f iff) ON (iff.num = i.num AND iff.num IS NULL)
LEFT JOIN (temp_a ta) ON (ta.num = i.num AND ta.num IS NULL)
LIMIT 100
于 2012-06-20T12:22:09.437 に答える