目前我有13个表,每个表约5-6列。在13个表中,4个表具有超过200,000(20百万)行,其中5-6列具有varchar(1000)或更多值。其余10个表有大约10000行,每行有5-6列,每列有varchar(1000)或更多值。每当我编写包含来自> = 3个表的数据的查询时,预期结果为1000行和5列,查询执行需要花费大量时间,大约(30分钟-2小时)。
我的系统大约有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);
答案 0 :(得分:0)
这绝对是基本的,所以我相信你已经做到了。但为了以防万一,请务必在my.ini文件中设置查询日志记录,看看是否可能无法正确设置索引。
log_queries_not_using_indexes = 1
slow_query_log = 1
slow_query_log_file = "E:/wamp/logs/slowquery.log"
答案 1 :(得分:0)
您要加入的字段是否为索引类型和类似数据类型?
另外,查看您的查询时,您似乎正在基于几个表之间的OR进行连接,我怀疑这可能会阻止MySQL使用索引。
使用显式连接尝试此操作,这使得连接更加明显,并为其发布EXPLAIN: -
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)