通过SQL查询有效地获取具有3列和8亿行的表的统计信息

时间:2014-04-30 14:22:26

标签: mysql sql sql-server windows-7

我在SQL服务器数据库中有一个包含3列和8亿行的数据表。

  locationID     cardID    value
  NY_xxxxx     xxxxxx    xxxx.xxxx   // x : integer digits from 0 to 9
  NY_xxxxx     xxxxxx    xxxx.xxxx  
  NY_xxxxx     xxxxxx    xxxx.xxxx  
  IA_xxxxx     xxxxxx    xxxx.xxxx  
  IA_xxxxx     xxxxxx    xxxx.xxxx  
  IA_xxxxx     xxxxxx    xxxx.xxxx  
  ...

我需要为同一位置计算不同数量的cardID。

另外,我需要计算处于相同状态的位置编号。例如,对于上表中的NY,我们有3个位置。

我还需要知道每个州的位置数,每个位置的cardID数以及每个州的cardID数。

如何有效地通过SQL查询获取这些统计信息?数据表大小很大。

1 个答案:

答案 0 :(得分:1)

OP可能已经知道这一点,但这里是如何得到答案,无视效率。首先,每个位置的卡片,如评论中所述:

SELECT locationid, COUNT(DISTINCT cardID)
FROM table 
GROUP BY locationid 

接下来每个州的情况相同。

SELECT substring(locationid, 1, 2) state, COUNT(DISTINCT cardID)
FROM table 
GROUP BY substring(locationid, 1, 2)

对于单个州,

select COUNT(DISTINCT cardID)
from table 
where substring(locationid, 1, 2) = 'NY'

第一个查询的问题是它会返回locationID,就像NY_1234一样。如果你没有记住NY_1234在外行人的条件下,例如罗切斯特,你必须走出你的数据库才能看到它是什么。

第二个查询效率低下,因为它必须在大量记录上应用子字符串函数。第三个是效率低下的,因为它必须扫描整个表格。

如果你有关系模型,你可以做这样的事情。

select municipality, count(distinct cardID)
from table join location on table.locationid = location.locationID
group by municipality

select stateCode, count(distinct cardID)
from table join location on table.locationid = location.locationID
group by stateCode

州代码将是纽约州,新泽西州等。如果您想要纽约,新泽西等,那将只是另一个领域。

最后,

select count(distinct cardID)
from table join location on table.locationid = location.locationID
where stateCode = 'NY'

后两个关系查询比单个表查询更快,因为它们不必使用函数。使用stateCode上的索引可以加快速度,但即使你没有,也会扫描一个小得多的表。