加速SQL子查询
我正在开发一个系统,任何数量的公司都可以将中小型企业信息上传到数据库并进行搜索 表加速SQL子查询,sql,postgresql,performance,subquery,Sql,Postgresql,Performance,Subquery,我正在开发一个系统,任何数量的公司都可以将中小型企业信息上传到数据库并进行搜索 表import\u data存储不同公司上传的SME信息。 每个公司上传的信息由表import\u data的company\u id列标识 CREATE TABLE import_data ( id uuid NOT NULL, # Indexed company_id integer NOT NULL, # Indexed business_name character va
import\u data
存储不同公司上传的SME信息。
每个公司上传的信息由表import\u data
的company\u id
列标识
CREATE TABLE import_data
(
id uuid NOT NULL, # Indexed
company_id integer NOT NULL, # Indexed
business_name character varying, # Indexed
no_of_rating double precision, # Indexed
no_of_reviews double precision, # Indexed
phone character varying, # Indexed
email character varying, # Indexed
address character varying, # Indexed
upserted_by integer, # Not indexed
upsert_date timestamp without time zone, # Not indexed
)
PARTITION BY LIST (company_id);
现在我正在开发一个推荐系统,将一个电话号码不存在于某家公司上传的数据中,但存在于另一家公司上传的数据中的记录推荐给第一家公司购买。
公司与其拥有的所有导入数据记录之间的关系存储在另一个表中import\u data\u company\u rel
。此表包括特定公司上载和购买的所有import\u数据
记录
CREATE TABLE import_data_company_rel
(
record_id uuid NOT NULL, # Indexed
company_id integer NOT NULL # Indexed
)
PARTITION BY LIST (company_id);
这两个表都是分区的,这样每个公司都将在自己的分区中存储数据
例如,id为1的公司将在import_data_1、import_data_company_rel_1中存储其数据,id为2的公司将在import_data_2中存储其数据,import_data_company_rel_2具有相同的表import_data和import_data_company_rel模式
这是一个SQL查询,用于获取特定公司的推荐记录,比如id为1
SELECT id,business_name,address
FROM import_data
INNER JOIN import_data_company_rel idcr ON import_data.id = idcr.record_id
WHERE idcr.company_id != 1
AND import_data.phone NOT IN (SELECT import_data.phone
FROM import_data
INNER JOIN import_data_company_rel idcr
ON import_data.id = idcr.record_id
WHERE idcr.company_id = 1)
LIMIT 100 OFFSET 0;
此查询获取第一页推荐结果,电话记录不包括在公司1的记录中
尽管这对少量记录有效,但此查询不能很好地随记录数扩展
当记录的数量以百万计时,它甚至在一个小时后仅仅获取100条记录都不会完成执行
我发现查询中减慢执行速度的部分是子查询
SELECT import_data.phone
FROM import_data
INNER JOIN import_data_company_rel idcr
ON import_data.id = idcr.record_id
WHERE idcr.company_id = 1
它将选择id为1的公司已拥有的所有电话号码,以便从建议中筛选。此查询将逐行扫描整个表
我不认为对表进行分区与慢查询有任何关系,因为即使没有分区,查询也很慢
explain (analyze, buffers, format text)
结果可在以下位置看到。
我正在开发postgesql v13.2
如何加快查询速度?有可能吗?感谢您的帮助。谢谢。您可以做两件事来提高性能:
VACUUM import_data_company_rel_1;
这将消除昂贵的堆获取
不存在:
import_data.phone NOT IN
(SELECT import_data.phone
FROM import_data
INNER JOIN import_data_company_rel idcr
ON import_data.id = idcr.record_id
WHERE idcr.company_id = 1)
可以重写为
NOT EXISTS
(SELECT 1
FROM import_data
INNER JOIN import_data_company_rel idcr
ON import_data.id = idcr.record_id
WHERE idcr.company_id = 1
AND import_data.phone = import_data.phone)
它是不存在还是存在?询问b/c我没有得到关于不存在的结果。并且在上存在一些结果。它应该是
不存在
。这两句话的意思是一样的:“这张唱片不在我的财产范围内”和“我不拥有任何与这张唱片相等的东西”。真空有助于完成死刑。我在一个新的数据库中使用NOT EXISTS子句进行测试。我不知道我是否做错了什么,或者连接同一个表import_数据时有什么问题,notexists似乎不起作用。以下是我尝试插入导入数据(公司id、id、电话)值(1,'b9c9d29b-cedf-45d8-afb4-92d67de0e021','1111111'),(1,'d335e5ae-b172-4372-af5a-b26f5715fc9b','2222');将值(1,'d335e5ae-b172-4372-af5a-b26f5715fc9b'),(1,'b9c9d29b-cedf-45d8-afb4-92d67de0e021')插入导入数据公司关系(公司id,记录id)代码>现在模拟公司2购买记录<代码>插入导入数据公司关系(公司id,记录id)值(2,'b9c9d29b-cedf-45d8-afb4-92d67de0e021')代码>但是查询没有给出结果。然后我发现这件衣服是这样的。有没有办法将查询的结果与子查询的结果连接起来?好吧,因为您有一个限制100
,所以您可能可以将不在
中,而不重写查询。