我有30万条记录(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为512 MB。哪里我错了?
查询是:
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,我会显示所有记录。
声明INDEXES:
i.m_id INDEX
im.id PRIMARY KEY
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
答案 0 :(得分: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?
答案 1 :(得分:-1)
有两个可能的原因,两者都可能有所贡献。 首先,尽量避免选择*。显式指定列将针对主数据库为每个连接查询保存,以反复查找列名。 第二个是你指定一个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