在SQL语句中有效表达多个元组对WHERE条件的方法

时间:2010-08-17 05:40:42

标签: python sql optimization postgresql

我想执行逻辑上等同于以下内容的SQL查询:

DELETE FROM pond_pairs
WHERE
  ((pond1 = 12) AND (pond2 = 233)) OR
  ((pond1 = 12) AND (pond2 = 234)) OR
  ((pond1 = 12) AND (pond2 = 8)) OR
  ((pond1 = 13) AND (pond2 = 6547)) OR
  ((pond1 = 13879) AND (pond2 = 6))

我将拥有数十万pond1 - pond2对。我有(pond1, pond2)的索引。

我有限的SQL知识提出了几种方法:

  1. 按原样运行整个查询。
  2. 将查询批处理为具有n WHERE条件
  3. 的较小查询
  4. pond1 - pond2对保存到新表中,并在WHERE子句中执行子查询以识别
  5. 将标识要删除的行的python逻辑转换为存储过程。请注意,我不熟悉编程存储过程,因此这可能涉及陡峭的学习曲线。
  6. 如果相关,我会使用postgres。

3 个答案:

答案 0 :(得分:1)

我将执行3.(使用JOIN而不是子查询)并测量DELETE查询的时间(不创建表和插入)。这是一个很好的起点,因为JOINing是非常常见和优化的程序,因此很难打败那个时间。然后,您可以将该时间与当前的方法进行比较。

您也可以尝试以下方法:

  1. 以与索引相同的方式对对进行排序。
  2. 使用方法2.从您的描述中删除(可能在单笔交易中)。
  3. 删除前的排序将提供更好的索引读取性能,因为硬盘驱动器缓存更有可能工作。

答案 1 :(得分:1)

如果要在一个DELETE中删除大量的pond1-pond2对,我会创建临时表并加入此表。

-- Create the temp table:
CREATE TEMP TABLE foo AS SELECT * FROM (VALUES(1,2), (1,3)) AS sub (pond1, pond2);

-- Delete
DELETE FROM bar 
USING  
  foo -- the joined table
WHERE 
  bar.pond1= foo.pond1 
AND 
  bar.pond2 = foo.pond2;

答案 2 :(得分:0)

有成千上万的对,你不能做1(按原样运行查询),因为SQL语句太长了。

如果您已经在表格中使用了对,那么

3就很好。如果没有,您需要先插入它们。如果以后不需要它们,也可以运行相同数量的DELETE语句而不是INSERT语句。

循环中准备好的语句怎么样,可能是批处理的(如果Python支持的话)

  1. 开始交易
  2. 准备声明“DELETE FROM pond_pairs WHERE((pond1 =?)AND(pond2 =?))”
  3. 遍历您的数据(在Python中),并使用一对(或添加到批处理)运行语句
  4. commit
  5. 这对来自哪里?如果您可以编写SELECT语句来标识它们,则可以将此条件移动到删除的WHERE子句中。

    DELETE FROM pond_pairs WHERE (pond1, ponds) in (SELECT pond1, pond2 FROM ......  )