SQL使用来自多个链接表的子查询获取计数

时间:2019-04-18 07:37:21

标签: sql-server

假设我有表1-4,所有其他表都链接到table1。就其价值而言,table1,table2和table3相对较小,但table4包含大量数据。

现在我有以下查询:

SELECT t1.id
    , (SELECT COUNT(*) FROM table2 WHERE table1_id = t1.id) AS t2_count
    , (SELECT COUNT(*) FROM table3 WHERE table1_id = t1.id) AS t3_count
    , (SELECT COUNT(*) FROM table4 WHERE table1_id = t1.id) AS t4_count
FROM table1 t1

由于子查询是相关/相关的,所以我认为必须有更好的方法(从性能角度考虑)来获取数据。

我尝试执行以下操作,但是它大大增加了执行时间(从大约2s到35s)。我猜想多个左联接会创建一个非常大的数据集?!

SELECT t1.id
    , COUNT(t2.id) AS t2_count
    , COUNT(t3.id) AS t3_count
    , COUNT(t4.id) AS t4_count
FROM table1 t1
    LEFT JOIN table2 t2 ON t2.table1_id = t1.id
    LEFT JOIN table3 t3 ON t3.table1_id = t1.id
    LEFT JOIN table4 t4 ON t4.table1_id = t1.id
GROUP BY t1.id

是否有更好的方法来计数?我不需要其他表中的数据。

更新:

Bart的answer让我想到table1_id列可以为空。我在IS NOT NULL子句中添加了WHERE检查,这使时间减少到1s。

SELECT t1.id
   , (SELECT COUNT(*) FROM table2 WHERE table1_id IS NOT NULL AND table1_id = t1.id) AS t2_count
   , (SELECT COUNT(*) FROM table3 WHERE table1_id IS NOT NULL AND table1_id = t1.id) AS t3_count
   , (SELECT COUNT(*) FROM table4 WHERE table1_id IS NOT NULL AND table1_id = t1.id) AS t4_count
FROM table1 t1

1 个答案:

答案 0 :(得分:1)

我想不是。如果执行SELECT COUNT(*) FROM [table],它将对表的PK进行计数。即使对于非常大的表,这也应该非常快。

您的table4是真实的表(不是视图,表值函数或其他看起来像表的表)吗?它有主键吗?如果是这样,我认为SELECT COUNT(*) FROM [table4]查询的性能不会显着提高。

也可能是您的table4具有很强的针对性(在多个连接的并发事务中),或者您的SQL Server正在做大量的IO或计算。我对此不能承担任何责任。您可能会尝试检查在物理上独立的测试服务器上的已还原数据库备份上查询是否还很慢。