2013-10-17 97 views
0

我有兩個用於兩個不同程序的表。每個程序都有一個特定的program_instance(program_instance)是該程序的年份。SQL根據某些列在同一個表中查找行

一個表被稱爲「登記者」,另一個表是「提名」 - 兩個程序在技術上沒有關係。

我一直在試圖從兩個表中獲得過去參與者的人數。供參考:

program_instance_id:

  • 5 = GC 2014
  • 3 = GC 2013
  • 1 = GC 2012
  • 4 = GE 2013
  • 2 = GE 2012

所以我在我的登記表上運行了這個查詢,它產生了913ms的結果:

SELECT  count(*) AS prev_enrollees 
FROM  outreach.enrollees e1 
WHERE e1.program_instance_id = 5 AND EXISTS 
    (SELECT * FROM outreach.enrollees e2 
      WHERE e1.first_name = e2.first_name 
      AND e1.last_name = e2.last_name 
      AND e1.address1 = e2.address1 
      AND e1.state = e2.state 
      AND e1.zip = e2.zip 
      AND e2.program_instance_id < 5); 

這個查詢,我的理解,會給我的行數在「參保」表,其中從當年的參與者(program_instance_id = 5)以前曾在一年入學。根據我的理解,它產生的結果非常準確。

所以......我在我的'提名'表上跑了這個EXACT查詢(改變表名)。提名錶幾乎具有「參與者」表的確切結構(某些欄目不同,但人員的信息欄位相同)。這個查詢在我取消之前運行了半個多小時。它並沒有像登記者表那樣出現幾乎即時的結果,我不知道爲什麼會花費更長的時間。

我可以想象,如果表中有更多的行,但參與者表比提名錶大約多50k行。

我也試過:

SELECT  count(*) AS prev_enrollees 
FROM  outreach_grow_education.nominations e1 
JOIN outreach_grow_education.nominations e2 ON e1.first_name = e2.first_name 
AND e1.last_name = e2.last_name 
AND e1.address1 = e2.address1 
AND e1.state = e2.state 
AND e1.zip = e2.zip 
AND 4 = e2.program_instance_id 
WHERE e1.id IS NOT NULL AND e1.program_instance_id = 2; 

唉,相同的結果。立即在註冊人結果,永不結束提名。

是否有任何其他的替代方案,我試圖實現,不會導致永無止境的循環?

+0

您使用的是MySQL還是SQL Server?請在問題上使用正確的數據庫標記。這對於基於性能的問題尤其重要。 –

+0

對不起,這是MySQL。可悲的是,我不知道有什麼區別。 –

回答

0

我建議檢查兩個表的索引,特別是在JOIN子句中使用的列:first_name,last_name,address1,state,zip和program_instance_id。機會是這些列中的一個或多個在「參與者」表中被編入索引,而不在「提名」中。

+0

我剛剛閱讀有關索引,因爲我收到有關您的答案的通知。這正是它的原因。我顯然有很多學習數據庫的知識。謝謝。 –

相關問題