2013-05-09 62 views
1

我正在使用MySQL world.sql数据库。究竟它是什么并不重要,但重要的要使用的模式是这样的:加速缓慢的SQL查询

CREATE TABLE city (
    name char(35), 
    country_code char(3), 
    population int(11), 
); 
CREATE TABLE country (
    code char(3), 
    name char(52), 
    population int(11) 
); 

有问题的查询,在英语中,“每个国家,给我的名字和人口众多,随着名称和人口对谁都有其人口占全国人口”

目前比例最高的城市,我有以下SQL:

SELECT t.name, t.population, c.name, c.population 
FROM country c 
JOIN city t 
ON t.country_code = c.code 
WHERE t.population/c.population = (
    SELECT MAX(tt.population/c.population) 
    FROM city tt 
    WHERE t.country_code = tt.country_code 
) 

目前,查询需要大约10分钟,我的SQLite运行数据库。 world.sql数据库不大(4000-5000行?),所以我猜我在这里做错了什么。

我目前没有任何类型的索引或任何东西:数据库是一个空数据库,其中输入了该数据集(https://dl.dropboxusercontent.com/u/7997532/world.sql)。任何人都可以给我任何我需要修复的指针,让它在合理的时间内运行?

编辑:那么这里是另外一个奇怪的问题:

这将运行在<2秒

SELECT t.name, t.population, c.name, c.population 
    FROM country c 
    JOIN city t 
    ON t.country_code = c.code 
    WHERE t.population * 1.0/c.population = (
     SELECT MAX(tt.population * 1.0/c.population) 
     FROM city tt 
     WHERE tt.country_code = t.country_code 
    ) 

虽然这需要10分钟跑

SELECT t.name, t.population, c.name, c.population 
    FROM country c 
    JOIN city t 
    ON t.country_code = c.code 
    AND t.population * 1.0/c.population = (
     SELECT MAX(tt.population * 1.0/c.population) 
     FROM city tt 
     WHERE tt.country_code = t.country_code 
    ) 

是解决再到当我做JOIN时,只要尽可能地将东西填入ON子句中?看来在这种情况下,我可以摆脱没有索引,如果我这样做...

+0

您可以尝试在city.country_code和country.code上创建索引,并查看它是否加快速度。 – Patashu 2013-05-09 01:08:06

回答

0

理想情况下,我会先下手指标,并考虑加入一个计算字段预先计算t.population/c.population成链接表

因此,对于每个国家和城市,您可以查看它的人口比例,而无需在RBAR中进行计算。

+0

RBAR意思是“通过Agonizing Row排”; SQL对数据集的效果最好,当你必须逐行执行某些操作时,它可能是一个错误的指示。 – 2013-05-09 23:34:21

0

我建议将数字主键添加到城市表中country_code的两个表和外键上。其中一个好处是性能更好,因为主键被编入索引。

编辑在这里

开始因为问题不要求您提供实际的比例,不必担心试图计算。该国人口最多的城市将拥有该国人口比例最高的城市。

1

对于每一个国家,拥有人口比例最高到它的国家的人口是城市最高人口的城市,所以试试这个:

SELECT t.name, t.population, c.name, c.population 
FROM country c 
    JOIN city t 
     ON t.country_code = c.code 
     And population = 
       (Select Max(population) from city 
       Where country_code = c.Code) 

但是这可能仍然没有太大改善性能..如果你没有任何指示。您需要在country.codecity.country_code上编制索引