2013-10-11 64 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)