2014-10-16 124 views
1

我想弄清楚爲什麼我的查詢需要這麼長時間。通常每個查詢需要大約60-90秒,並且執行多次。MySQL新加入的查詢需要太長的子查詢

舊查詢:

 "select * from $table where type = '".$type."' and transdate >= '".$begdate."' and 
     transdate<='".$enddate."' and customerin (select customer from master 
     where targetaccount='Y') "; 

新查詢:

$q = "SELECT * FROM activity INNER JOIN custactivities ON 
    activity.activityID = custactivities.activityID WHERE type = '$type' AND 
    transdate BETWEEN '$begdate' AND '$enddate' AND custnum IN 
    (SELECT customer FROM master WHERE targetaccount = 'Y') 
    GROUP BY custactivities.customer"; 

原始查詢約需0.15秒和新的查詢每次查詢需要大約60-90秒。

這確實有一些PHP,但查詢不是問題。

任何意見非常感謝。

+1

打印生成的查詢,我們不需要看到你的PHP。另外,你可以通過使用explain來了解你的查詢是否適當地使用了索引,學會調試你的代碼和查詢,如果沒有你的數據庫結構,我們也無能爲力。 – 2014-10-16 20:02:10

+1

爲什麼使用'group by'沒有聚合函數和'select *'? – 2014-10-16 20:04:38

+0

@DanyCaissy我拿出了大部分的PHP。它仍然需要在那裏,以提醒它是一個變量。然而,還有一個關鍵的習慣,然而,他們中沒有一個我可以使用,因爲有一個領域非常具體,我無法獲得這些數據。 @GordonLinoff是的,'選擇*'我可以誠實替換。但我懷疑這會造成巨大的時差。沒有聚合,因爲沒有任何功能匹配我所需要的。如果有的話,我只需要替換'select *'。 你想讓我發佈'show create table'嗎? – Twister1002 2014-10-16 20:20:09

回答

2

添加索引到下面的列,如果你沒有

activityID on both table 
type - if it's numeric, don't use the ' 
transdate 
targetaccount - if you can, use numeric, or enum definition for that column for better indexing 

做,如果你的主表是不符合其中targetaccount =「Y」,可以單獨給另一個查詢太大,用php取數據並用implode將數組插入到查詢中,而不是使用子查詢。

從不使用*,正如ChrisS所提到的。

這裏是一個小的代碼片段PHP與MySQL

$cust = array(); 
$sql = 'SELECT customer FROM master WHERE targetaccount = "Y"'; 
$query = mysql_query(); 
if ($query) { 
    while ($row = mysql_fetch_row($query)) { 
     $cust[] = $row[0] 
    } 
} 

$sql = "select * from $table where type = '".$type."' and transdate >= '".$begdate."' and 
     transdate<='".$enddate."'" . (count($cust) ? ' AND custnum IN ('.implode(', ', $cust).')' : ''); 

我沒有測試過,但我覺得現在你看到這一點。

+0

我嘗試將主服務器分離到另一個查詢中,但未能提供正確的信息。有時候它也會拋出一個錯誤,當查詢不會返回任何結果時。 (我知道錯誤應該在我的部分處理,只是讓你知道) 我同意'targetaccount'是數字,但是,我沒有設計這個數據庫。我正在收拾垃圾。 另外,是什麼讓'select *'這樣一件壞事?我讀過它據說會減慢查詢速度,但我從未見過這種情況的跡象。 – Twister1002 2014-10-16 20:27:53

+0

這會降低查詢速度,是的。如果你每秒只有少數幾個查詢的訪問者,這並不是很多,但是如果你有數以百萬計的查詢的數百萬訪問者,那麼需要很多時間 – 2014-10-16 20:30:50

+0

。我欣賞那一點信息。 – Twister1002 2014-10-16 20:35:06

1

你可以加入'主'嗎?這可以加快我的想法。你放緩很可能是這個子選擇。另外,僅僅爲了內存管理的緣故,你可能不希望只爲你需要的列做'SELECT *',而是'SELECT col1,col2'。

+0

雖然加入'master'表工作並massivly提高了查詢的時間,是什麼讓新查詢減慢沒有'master'連接? – Twister1002 2014-10-16 20:28:51

+1

您正在比較每一行到子查詢返回的列表。當你加入時,先編譯一個列表,然後用WHERE縮小它的範圍。基本上,你的查詢是走出去,抓住所有的行,而不是在主人過濾,然後檢查每一行到列表主返回。 – ChrisStillwell 2014-10-16 20:40:03