2011-01-22 70 views
3

我的查詢是這樣如何用兩個where子句優化SQL查詢?

SELECT * FROM tbl1 
JOIN tbl2 ON something = something 
WHERE 1 AND (tbl2.date = '$date' OR ('$date' BETWEEN tbl1.planA AND tbl1.planB)) 

當我運行此查詢,它比例如該查詢

SELECT * FROM tbl1 
JOIN tbl2 ON something = something 
WHERE 1 AND ('$date' BETWEEN tbl1.planA AND tbl1.planB) 

SELECT * FROM tbl1 
JOIN tbl2 ON something = something 
WHERE 1 AND tbl2.date = '$date' 

在本地主機,第一要慢得多查詢大約需要0.7秒,第二個查詢大約0.012秒,第三個查詢大約0.008秒。

我的問題是你如何優化這個?如果當前我的表中有1000行,並且需要0.7秒來顯示第一個查詢,那麼如果我有10.000行,則需要7秒?與第二個查詢(0.12秒)和第三個查詢(0.08)相比,這是一個巨大的減速。

我試過添加索引,但結果沒有什麼不同。

感謝

編輯:此應用程序將只在本地工作,所以無需擔心速度在網上。

對不起,我沒有包含EXPLAIN,因爲我真正的查詢要複雜得多(約5個連接)。但是聯結(我認爲)並不重要,因爲我已經嘗試省略它們,並且仍然獲得與上述大致相同的結果。

日期屬於tbl1,planA和planB屬於tbl2。我試着給tbl1.date,tbl2.planA和tbl2.planB添加索引,但結果不明顯。

按照schema的意思是MyISAM或InnoDB?這是MyISAM。

好的,我馬上發佈我的查詢。希望這不是令人困惑。

SELECT * 
FROM tb_joborder jo 
LEFT JOIN tb_project p ON jo.project_id = p.project_id 
LEFT JOIN tb_customer c ON p.customer_id = c.customer_id 
LEFT JOIN tb_dispatch d ON jo.joborder_id = d.joborder_id 
LEFT JOIN tb_joborderitem ji ON jo.joborder_id = ji.joborder_id 
LEFT JOIN tb_mix m ON ji.mix_id = m.mix_id 
WHERE dispatch_date = '2011-01-11' 
OR '2011-01-11' 
BETWEEN planA 
AND planB 
GROUP BY jo.joborder_id 
ORDER BY customer_name ASC 

而且描述輸出

id select_type  table type possible_keys key  key_len  ref  rows Extra 
1 SIMPLE jo ALL  NULL NULL NULL NULL 453  Using temporary; Using filesort 
1 SIMPLE p eq_ref PRIMARY  PRIMARY  4 db_dexada.jo.project_id  1  
1 SIMPLE c eq_ref PRIMARY  PRIMARY  4 db_dexada.p.customer_id  1  
1 SIMPLE d ALL  NULL NULL NULL NULL 2048 Using where 
1 SIMPLE ji ALL  NULL NULL NULL NULL 455  
1 SIMPLE m eq_ref PRIMARY  PRIMARY  4 db_dexada.ji.mix_id  1  
+1

你有什麼指數? 'DESCRIBE SELECT(你的查詢)'的輸出是什麼? – bdonlan 2011-01-22 10:03:59

+0

另外,這些表的模式是什麼? – bdonlan 2011-01-22 10:08:43

回答

1

您可以只使用UNION合併第二和3d查詢的結果。

More about UNION。

想到的
1

第一件事是聯盟兩個:

SELECT * FROM tbl1 
JOIN tbl2 ON something = something 
WHERE 1 AND ('$date' BETWEEN planA AND planB) 

UNION ALL 

SELECT * FROM tbl1 
JOIN tbl2 ON something = something 
WHERE 1 AND date = '$date' 

您提供太少進行優化。我們對你的數據結構一無所知。

0

即使最慢的查詢通常是由於查詢本身或使用的表的索引設置引起的,您也可以嘗試使用MySQL Query Profiler查找瓶頸的位置。它從版本5.0.37開始已經被實現到MySQL中。

之前您開始查詢,激活探查這一說法:

mysql> set profiling=1; 

現在執行的長的查詢。

隨着

mysql> show profiles; 

你現在可以找出內部號碼(查詢號碼)你長的查詢了。

如果現在執行下面的查詢,你會得到很多的什麼花了多長時間的詳細信息:

mysql> show profile for query (insert query number here); 
(example output) 
+--------------------+------------+ 
| Status    | Duration | 
+--------------------+------------+ 
| (initialization) | 0.00005000 | 
| Opening tables  | 0.00006000 | 
| System lock  | 0.00000500 | 
| Table lock   | 0.00001200 | 
| init    | 0.00002500 | 
| optimizing   | 0.00001000 | 
| statistics   | 0.00009200 | 
| preparing   | 0.00003700 | 
| executing   | 0.00000400 | 
| Sending data  | 0.00066600 | 
| end    | 0.00000700 | 
| query end   | 0.00000400 | 
| freeing items  | 0.00001800 | 
| closing tables  | 0.00000400 | 
| logging slow query | 0.00000500 | 
+--------------------+------------+ 

這是一個更一般的,行政的方法,但可以幫助縮小甚至找出慢查詢的原因非常好。

關於如何使用MySQL Query Profiler的一個很好的教程可以在MySQL文章中找到here