我需要运行以下类型的查询:
SELECT * FROM A CROSS JOIN B WHERE myfunction(A.x,B.y) = Z
由于查询速度慢,我想使用所有可用的处理器加速查询。 我对关系数据库只有非常基本的知识,所以即使是“明显的”评论也是受欢迎的。
什么是合理的解决方案? 目前,使用50个处理器进行10k x 2M查询,下面提出的天真拆分大约需要20分钟。
我正在考虑并行运行B部分的交叉连接。 B将被ID(整数主键)的值分割
SELECT * FROM A CROSS JOIN B WHERE myfunction(A.x,B.y) = Z AND A.id BETWEEN N and M.
使用gnu parallel运行多个“psql -d mydatabase subqueryNumberX.sql”命令。
有些问题:
如果我有一个索引表T并在另一个查询中使用SELECT,那么搜索中会使用T的索引吗?或者这个subSELECT摧毁它?
在我上面的查询中,选择表的一部分(WHERE A.ID BETWEEN N和M)是否会阻止使用索引?
当表上的(慢)交叉连接正在进行时,其他操作(下一次交叉连接)可以访问这样的表吗?
答案 0 :(得分:0)
你的问题(仍然)相当含糊。
对于交叉连接,索引不一定有用,但它取决于索引的列以及查询中引用的列和表中行的大小。如果索引位于相关列上,那么优化器可能只会执行索引'扫描而不是全表扫描'并从较少量的I / O中受益。但是,由于您有SELECT *
,因此您要从A
和B
中选择所有列,因此需要读取整行(但请参阅第2点)。在查询中没有子选择,所以询问子选择是否会破坏任何东西都是不明智的。
名义上,您可以从将WHERE子句移动到子选项中获得一些好处,例如:
SELECT *
FROM (SELECT * FROM A WHERE A.id BETWEEN N AND M) AS A1
CROSS JOIN B
WHERE myFunction(A1.x, B.y) = Z
然而,这将是一个微弱的优化器,不会自动执行此操作。范围条件可能使A.id
上的索引具有吸引力,尤其是如果M和N代表A.id
中值的总范围的一小部分。因此,优化器应使用带有A.id
的索引作为前导或唯一组件,以允许它加速查询。条件不会阻止使用任何索引 - 索引几乎肯定不会被使用。
慢速查询不会禁止其他查询;它可能会在运行时禁止更新,或者它可能会强调DBMS的MVCC(多版本并发控制)机制。