多表查询的SQL优化

时间:2011-01-10 07:16:57

标签: mysql sql query-optimization

我正在使用庞大的失业数据数据库,这些数据来自劳工统计部门提供的文件:

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;

此时我对数据库和查询优化知之甚少 - 任何人都可以给我任何关于我的查询的指针,或者向数据库本身添加索引等以加快我的交易吗?

3 个答案:

答案 0 :(得分:0)

我的猜测是区号/文本正在慢慢改变数据,所以为什么不将它们放入自己的表中。然后你可以用一个id替换它们,这个id会缩小那个表的大小,这样可以更快地从那个表中读取。

由于您实际上并未在第一个查询中使用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)

答案 1 :(得分:0)

您的问题可能是LEFT加入。你的意思是把它变成普通的连接吗? (如果右边的表中没有匹配的记录,则左连接将返回null)

答案 2 :(得分: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