如何优化这个巨大而丑陋的查询,忽略重复?

时间:2010-12-03 09:38:35

标签: sql sqlite optimization duplicates

我不是SQL专家,这是我的SQLite查询表“Query”(键:SystemId,TopicId,DocumentId,所有也是外键),它获取外键并插入避免重复。但它是巨大的,丑陋的,我必须执行数千次:

command.CommandText = "INSERT INTO Query (SystemId, TopicId, DocumentId) " +
  "(SELECT Id FROM System WHERE Tag = @SystemTag COLLATE NOCASE), " +
  "(SELECT Id FROM Topic WHERE Number = @TopicNumber COLLATE NOCASE), " +
  "(SELECT Id FROM Document WHERE Number = @DocNumber COLLATE NOCASE) " +
  "WHERE NOT EXISTS (SELECT 1 FROM Query WHERE " +
    "SystemId = (SELECT Id FROM System WHERE Tag = @SystemTag) AND " +
    "TopicId = (SELECT 1 FROM Topic WHERE Number = @TopicNumber) AND " +
    "DocumentId = (SELECT Id FROM Document WHERE Number = @DocNumber))";

问题:任何告诉sql的方法“不要担心重复,忽略插入语句”。或者也许使用变量/临时表,AD语句?

编辑:直接查询:

INSERT INTO Query (SystemId, TopicId, DocumentId)
  (SELECT Id FROM System WHERE Tag = @SystemTag COLLATE NOCASE),
  (SELECT Id FROM Topic WHERE Number = @TopicNumber COLLATE NOCASE),
  (SELECT Id FROM Document WHERE Number = @DocNumber COLLATE NOCASE)
  WHERE NOT EXISTS (SELECT 1 FROM Query WHERE 
    SystemId = (SELECT Id FROM System WHERE Tag = @SystemTag) AND
    TopicId = (SELECT 1 FROM Topic WHERE Number = @TopicNumber) AND
    DocumentId = (SELECT Id FROM Document WHERE Number = @DocNumber));

3 个答案:

答案 0 :(得分:1)

要防止插入副本,您需要做两件事:

一个表定义,用于将列标识为需要唯一。例如:

CREATE TABLE Query (
 SystemId INTEGER, 
 TopicId INTEGER,
 DocumentId INTEGER,
 PRIMARY KEY (SystemId, TopicId, DocumentId));

CREATE TABLE Query (
 SystemId INTEGER, 
 TopicId INTEGER,
 DocumentId INTEGER,
 PRIMARY KEY (SystemId, TopicId, DocumentId));

conflict clause。您可以通过以下两种方式之一执行此操作:在表定义中保留(如上所述将使其默认为IGNORE,这几乎是您想要的),或者在您的插入命令中:

INSERT OR IGNORE INTO Query...

如果您使用UNIQUE约束进行表设置,则实际上不需要更改INSERT查询(除了删除遗漏的WHERE NOT EXISTS位。

缺点是,是的,它会使您的代码尝试各种插入并失败。但从另一个角度来看:它使您的数据库按照您希望的方式运行。这是使用数据库的关键,您不希望在进行操作时对所有表进行全手动扫描。你想让数据库做脏工作。

答案 1 :(得分:0)

在关于忽略重复项的问题中,您需要调查DISTINCT

答案 2 :(得分:0)

我不知道你是如何在SQL Lite中执行此操作的(如果存在任何特定于平台的语法问题),但删除重复项的常用方法是使用GROUP BY。

W3Schools在通用SQL方面有一个很好的例子:

http://www.w3schools.com/sql/sql_groupby.asp

另一个选项是DISTINCT,但这可能会在大型数据集中出现问题。

最后,作为观察,你可能想要研究使用JOIN而不是嵌套的SELECT。

http://www.w3schools.com/sql/sql_join.asp