2013-10-11 42 views
-1

目前我有13个表,每个表约有5-6列。在13个表中,4个表具有超过200,000(20万个)行,其中具有varchar(1000)或更大值的5-6列。其余10个表格大约有10000行,每行5到6列,每个都有varchar(1000)或更多值。每当我写包含> = 3表的数据的查询时,预期结果为1000行和5列,查询执行花费大量时间,大约(30分钟-2小时)。如何加快涉及多个表的MySQL查询的执行

我有大约12GB RAM和x86_64 x86_64 x86_64 GNU/Linux系统。

什么是可能的方法来大幅减少查询执行时间?

select a.d_id, 
     a.d_n, 
     a.t_id, a.act, 
     a.pm, 
     b.d_t, 
     b.d_d, 
     b.pm, 
     b.mec_of_act, 
     b.d_g, 
     b.d_c, 
     c.n_id, 
     c.s_name, 
     c.s_status, 
     c.s_p, 
     c.dis 
from d_tar a, 
     d_char b, 
     ct c, 
     c_int d, 
     d_s e, 
     d_b f 
where a.d_id=b.d_id 
&&  a.d_id=e.d_id 
&&  t_id='847' 
&&  a.d_id=f.d_id 
&&  d.n_id=c.n_id 
&&  (d.in_name=b.d_n 
      or d.in_name=e.snym 
      or d.in_name=f.b_name); 
+3

向我们显示查询,解释计划.. –

+0

您的查询需要优化。我正在研究3倍差的服务器,并从4个表中获取数据,从中获得10 + M个记录,其余每个记录约为0.5 + M。服务器忙时大约需要1-2秒。 –

+0

我建议你学会使用显式连接 - 'FROM d_tar a JOIN d_char b ON a.d_id = b.d_id JOIN ...'。它使得更容易看到发生了什么。 – Dukeling

回答

0

这绝对是基本的,所以我敢肯定,你已经做到了。但为防万一,请确保在my.ini文件中设置查询日志记录,并查看是否可能您的索引不总是正确设置。

log_queries_not_using_indexes = 1 
slow_query_log = 1 
slow_query_log_file = "E:/wamp/logs/slowquery.log" 
0

您正在加入索引和相似数据类型的字段?

另外,看着你的查询,你似乎正在做一些基于或两个表之间的联接,我怀疑这可能会阻止MySQL有用地使用索引。

试试这个有明确的加入,这使得连接更明显,并张贴了解释它: -

SELECT a.d_id, 
     a.d_n, 
     a.t_id, 
     a.act, 
     a.pm, 
     b.d_t, 
     b.d_d, 
     b.pm, 
     b.mec_of_act, 
     b.d_g, 
     b.d_c, 
     c.n_id, 
     c.s_name, 
     c.s_status, 
     c.s_p, 
     c.dis 
FROM d_tar a 
INNER JOIN d_char b ON a.d_id=b.d_id 
INNER JOIN d_b f ON a.d_id=f.d_id 
INNER JOIN d_s e ON a.d_id=e.d_id 
INNER JOIN c_int d ON d.in_name IN (b.d_n, e.snym, f.b_name) 
INNER JOIN ct c ON d.n_id=c.n_id 
WHERE a.t_id='847' 

编辑 - 如果在不同的列名的加入是防止有用的索引被使用,那么也许以下将工作(虽然这假设c_int.n_id是唯一的): -

SELECT a.d_id, 
     a.d_n, 
     a.t_id, 
     a.act, 
     a.pm, 
     b.d_t, 
     b.d_d, 
     b.pm, 
     b.mec_of_act, 
     b.d_g, 
     b.d_c, 
     CASE WHEN c1.n_id IS NOT NULL THEN c1.n_id WHEN c2.n_id IS NOT NULL THEN c2.n_id WHEN c3.n_id IS NOT NULL THEN c3.n_id END AS n_id, 
     CASE WHEN c1.n_id IS NOT NULL THEN c1.s_name WHEN c2.n_id IS NOT NULL THEN c2.s_name WHEN c3.n_id IS NOT NULL THEN c3.s_name END AS s_name, 
     CASE WHEN c1.n_id IS NOT NULL THEN c1.s_status WHEN c2.n_id IS NOT NULL THEN c2.s_status WHEN c3.n_id IS NOT NULL THEN c3.s_status END AS s_status, 
     CASE WHEN c1.n_id IS NOT NULL THEN c1.s_p WHEN c2.n_id IS NOT NULL THEN c2.s_p WHEN c3.n_id IS NOT NULL THEN c3.s_p END AS s_p, 
     CASE WHEN c1.n_id IS NOT NULL THEN c1.dis WHEN c2.n_id IS NOT NULL THEN c2.dis WHEN c3.n_id IS NOT NULL THEN c3.dis END AS dis 
FROM d_tar a 
INNER JOIN d_char b ON a.d_id = b.d_id 
INNER JOIN d_b f ON a.d_id = f.d_id 
INNER JOIN d_s e ON a.d_id = e.d_id 
LEFT JOIN c_int d1 ON d1.in_name = b.d_n 
LEFT JOIN c_int d2 ON d2.in_name = e.snym 
LEFT JOIN c_int d3 ON d3.in_name = f.b_name 
LEFT JOIN ct c1 ON d1.n_id = c1.n_id 
LEFT JOIN ct c2 ON d1.n_id = c2.n_id 
LEFT JOIN ct c3 ON d1.n_id = c3.n_id 
WHERE a.t_id='847' 
AND (c1.n_id IS NOT NULL 
OR c2.n_id IS NOT NULL 
OR c2.n_id IS NOT NULL)