Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从SQL表计算空关系_Sql_Sqlite_Postgresql - Fatal编程技术网

从SQL表计算空关系

从SQL表计算空关系,sql,sqlite,postgresql,Sql,Sqlite,Postgresql,我试图统计那些在我们的系统中没有任何文章的作者,这会聚集网站上的作者。我有一个查询正在运行,但没有执行 到目前为止,我提出的最好的问题是: select count(*) as count_all from ( select authors.id from authors left outer join site_authors on site_authors.author_id = authors.id left outer join articles on articles.

我试图统计那些在我们的系统中没有任何文章的作者,这会聚集网站上的作者。我有一个查询正在运行,但没有执行

到目前为止,我提出的最好的问题是:

select count(*) as count_all
from (
  select authors.id
  from authors
  left outer join site_authors on site_authors.author_id = authors.id
  left outer join articles on articles.site_author_id = site_authors.id
  group by authors.id
  having count(articles.id) = 0
) a;
但是,子查询效率相当低。我希望能有办法把它弄平。我有几个类似的查询,它们在左侧外部联接上添加了额外的条件,因此在我的模式中添加count列实际上不是一个选项


额外麻烦:这是一个跨平台查询,需要同时对pgSQL、SQLite和MySQL进行操作。

您可以尝试稍微不同的查询,但我不确定它是否会更快:

select count(*)
from authors as a
where not exists (
    select b.id
    from site_authors as b
        inner join
    articles as c
    on a.id=b.author_id and b.id=c.site_author_id)
当然,我认为您在表上有适当的索引:

  • 站点作者:唯一(作者id,id)
  • 文章:非唯一(站点\作者\ id)

使用NOT IN可能比使用join更简单、更快。Sql处理器在使用索引方面非常聪明,即使它看起来很迟钝。大概是这样的:

Select count(*)
  from authors
 where id not in (select author_id from site_authors)
   and id not in (select site_author_id from articles);

确保编者id和站点编者id已编入索引。优化器将注意到您正在执行的操作,并为“NOT IN”子句创建索引查找。

假设“正常”联接更简单、更快,您可以从总作者数中减去有文章的作者数:

SELECT (SELECT COUNT(*)
        FROM authors) -
       (SELECT COUNT(DISTINCT site_authors.author_id)
        FROM site_authors
        JOIN articles ON articles.site_author_id = site_authors.id)
或者,尝试子查询:

SELECT COUNT(*)
FROM authors
WHERE id NOT IN (SELECT site_authors.author_id
                 FROM site_authors
                 JOIN articles ON articles.site_author_id = site_authors.id)

不会再慢了。(验证smomething不存在要比计算元组并将结果与零进行比较便宜)是的,PG显示它的速度是原来的两倍。原始查询的成本约为106,没有子计划。您的建议花费了214美元,还有一个子计划。@SEK这是建立索引和收集/重建STA的吗?是的。索引所有不起作用的外键。authors.id不是站点作者id的fk。它需要对站点作者/文章的内部联接执行子查询。然而,这可能更有效率。我来试试看这些数字是否有效。啊,是的。我没有注意到那是间接的。not in子句可以应用于select/join。现在我很好奇。让我知道,效率要低得多。PG没有把它作为索引,而不是在前者可能是个好主意,但这种方法对我的其他查询不起作用,比如在上个月没有发表任何文章的作者。第一种方法似乎很有希望,但取决于让它有效地使用索引联接。例如,站点作者比作者多得多,所以最好对作者进行内部连接,而不是进行区分。当我用这个额外的内部连接测试它时,它将成本从10k降到了112,只比我原来的查询多6倍。另一方面,我已经查询了完整计数,因此我可能能够对其进行调优,以便它在应用程序方面做更多的工作