2011-01-10 112 views
0

我有一個龐大的數據庫可從勞工統計部門從這裏中的文件生成的失業數據的工作:SQL優化查詢

ftp://ftp.bls.gov/pub/time.series/la/

我建幾個查詢拉起數據部分,並且在爲所有表添加索引後,我可以想到許多數據仍然需要幾秒或更長時間。

我的第一個查詢返回有失業數據可用的狀態下的所有子區域。將索引添加到Series表和Area表後,執行時間從2秒變爲0.9秒,但我無法將其降低。我認爲DISTINCT需要這麼長時間,但有必要保留記錄以避免重複。

SELECT DISTINCT series.area_code, area.area_text FROM Alabama 
LEFT JOIN series ON Alabama.series_id=series.series_id 
LEFT JOIN area ON series.area_code=area.area_code 
WHERE area.area_type_code != 'A'; 

我的第二個查詢,這實際上拉起每個領域的數據,僅在0.3秒,即使它拉遠記錄:

USE unemploymentdata; 
SELECT DISTINCT * FROM Alabama 
LEFT JOIN series ON Alabama.series_id=series.series_id 
LEFT JOIN area ON series.area_code=area.area_code 
WHERE area.area_type_code != 'A' 
AND area.area_code = 'CA011420' 
AND year > 2000; 

我對數據庫非常小知識並在這一點上查詢優化 - 任何人都可以給我任何指針在我的查詢,或者在數據庫本身添加索引等,以加快我的交易?

+0

**請包括執行計劃**以及 – ajreal 2011-01-10 07:20:51

+0

你能發佈索引你爲每個表格創建的,還有「解釋選擇...」的結果?另外,當條件更受限制,使用不同的數據庫時,爲什麼第二個查詢會提取更多數據? – Jaydee 2011-01-10 11:12:34

回答

0

我的猜測是,區號/文本正在慢慢改變數據,所以爲什麼不把它們放到自己的表中。然後,您可以用阿拉巴馬錶替換它們,這樣會縮小表格的大小,從而更快地從表格中讀取表格。

由於在第一個查詢中實際上沒有使用來自alabama表的任何數據,所以在沒有表更改的情況下可能會更快。

SELECT DISTINCT series.area_code, area.area_text 
FROM series 
LEFT JOIN area ON series.area_code=area.area_code 
WHERE area.area_type_code != 'A'; 
and series_id in (select series_id from Alabama) 
+0

我直接從BLS複製表結構,我假設他們會在最優化的配置中使用它。 – MarathonStudios 2011-01-10 07:33:55

0

您的問題可能是左連接。你是否想讓它成爲一個正常的連接? (如果右表中沒有匹配的記錄,則左連接將返回null)

0
SELECT DISTINCT 
     series.area_code, 
     area.area_text 
FROM Alabama LEFT JOIN 
     series ON Alabama.series_id=series.series_id LEFT JOIN 
     area ON series.area_code=area.area_code 
WHERE area.area_type_code != 'A'; 

您可以將它更改爲INNER JOINS嗎?

SELECT DISTINCT 
     series.area_code, 
     area.area_text 
FROM  Alabama INNER JOIN 
     series ON Alabama.series_id=series.series_id INNER JOIN  
     area ON series.area_code=area.area_code 
WHERE area.area_type_code != 'A' 

是否需要阿拉巴馬錶?如果你像我在這裏一樣刪除它,你會得到相同的結果嗎?

SELECT DISTINCT 
     series.area_code, 
     area.area_text 
FROM  series INNER JOIN 
     area ON series.area_code = area.area_code 
WHERE area.area_type_code != 'A' 

關於系列表的同樣問題,可以刪除嗎?

SELECT DISTINCT 
     area.area_code, 
     area.area_text 
FROM  area 
WHERE area.area_type_code != 'A' 

如果不是,則索引它。

首先是區域表。添加具有以下列的索引

area_type_code, area_code, area_text 

該系列表(測試哪個更快。)

series_id, area_code 

area_code, series_id 

阿拉巴馬錶 創建簡單的指數具有以下列

series_id