2011-01-10 225 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