两个值之间的PostgreSQL连接
我有下面的表格,并试图查找数十万个城市的县代码两个值之间的PostgreSQL连接,postgresql,between,cross-join,Postgresql,Between,Cross Join,我有下面的表格,并试图查找数十万个城市的县代码 create table counties ( zip_code_from char(5) not null, zip_code_thru char(5) not null, county_code char(3) not null ); create table cities ( city text not null, zip_code char(5) not null ); 我的第一种方法是在
create table counties (
zip_code_from char(5) not null,
zip_code_thru char(5) not null,
county_code char(3) not null
);
create table cities (
city text not null,
zip_code char(5) not null
);
我的第一种方法是在连接中使用“中间人”:
select
ci.city, ci.zip_code, co.county_code
from
cities ci
join counties co on
co.zip_code between ci.zip_code_from and ci.zip_code_thru
我知道在甲骨文界,这是不受欢迎的,事实上,表现似乎很糟糕。处理大约16000个城市需要8分钟。邮政编码表有大约80000条记录。我猜这个语法是一个美化的交叉连接
from和thru代码都是索引的,我可以控制结构,因此如果有帮助,我可以更改表
我唯一的另一个想法是继续,将表格扩展到所有可能的值——类似于以下内容:
select
generate_series (
cast (zip_code_from as int),
cast (zip_code_thru as int)
) as zip_code,
*
from counties
这会将数据扩展到超过200000条记录,这并不是什么大问题,但我不确定这是否是我唯一的途径来进行不可怕的查询
我猜想,即使是在运行中这样做并且没有索引,也比我的联接中的之间的更好,但是我希望有一种替代方法,无论是在SQL方面还是在表本身的结构方面
我曾在其他DBMS平台上看到过这个问题,但我已经能够用PostgreSQL创造出在其他数据库中不可能(或不实用)的小奇迹,所以我希望我错过了一些东西。几个月后,这个问题再次出现,我决定测试我的一些理论
原始查询:
select
ci.city, ci.zip_code, co.fips_code
from
cities ci
join counties co on
ci.zip_code between co.from_zip_code and co.thru_zip_code
实际上实现了笛卡尔函数。查询返回34000行,耗时597秒
如果我“预分解”邮政编码范围为离散记录:
with exploded_zip as (
select
generate_series (
cast (from_zip_code as int),
cast (thru_zip_code as int)
)::text as zip_code,
*
from counties
)
select
ci.city, ci.zip_code, co.fips_code
from
cities ci
join exploded_zip co on
ci.zip_code = co.zip_code
查询返回完全相同的行,但在2.8秒内完成
因此,似乎底线是在联接(或任何不等式)中使用介于之间是一个非常糟糕的主意。您是否有城市(邮政编码)和县(邮政编码从,邮政编码到)
)的索引?作为了解邮政编码的人,我想说您对县的“从到”方法是有缺陷的。没有可以指定给县的邮政编码范围。一些邮政编码实际上跨越多个县。此外,一些城市有几十个邮政编码。这是假设您使用的是美国邮政编码和美国县。@a_horse_和_no_name在邮政编码_from、邮政编码_thru(一个单独的索引,而不是两个单独的索引)上有一个索引,在cities.Zip_代码上没有索引。查询正在扫描整个cities表,所以我认为这不会有帮助。会吗?@CoryatJohn我发现你是对的。在许多情况下,我发现三个县的邮政编码相同(即费尔法克斯,SC 29827),我们必须手动查找。如果你有建议,我会张开双臂欢迎他们。你看过人口普查档案网站了吗?它包含县和“地方”的多边形,加上地方(城市)应该已经具有正确的县FIPS代码。我建议你去寻找那些资源,而不是试图用邮政编码来捏造它。如果你的城市数据库有一个点,你也可以使用县的多边形来做一个简单的多边形点分析,我想你会发现它几乎100%准确。我会用这种方法。