我有两个表,task_list_sharee
和task_list_assignee
。它们都引用了task_list
表。
还有一个task
表,其中包含对task_list
表的引用,因为task
中始终存在task_list
。
鉴于task
,我想知道task_list_sharee
或task_list_assignee
是否有值。现在我将它作为两个SQL语句来执行,如下所示:
SELECT count(*)
FROM task_list_assignee a
INNER JOIN task_list l ON l.uid = a.task_list_uid
INNER JOIN task t ON t.task_list_uid = l.uid
WHERE t.uid = ?
SELECT count(*)
FROM task_list_sharee s
INNER JOIN task_list l ON l.uid = s.task_list_uid
INNER JOIN task t ON t.task_list_uid = l.uid
WHERE t.uid = ?
如果其中任何一个非零,那我就是平底船。我认为这必须只是一个SQL语句,但我有点难过。
答案 0 :(得分:1)
多个连接的完整计数性能(LEFT JOIN
更多)可能会很快恶化。虽然您只需要证明存在单行,但不需要这样做。使用EXISTS
- 名称为true - 以允许最佳查询计划:
SELECT EXISTS (
SELECT 1
FROM task t
WHERE t.uid = ? -- provide uid here
AND (
EXISTS (
SELECT 1
FROM task_list_assignee
WHERE task_list_uid = t.task_list_uid
)
OR EXISTS (
SELECT 1
FROM task_list_sharee
WHERE task_list_uid = t.task_list_uid
)
)
);
应比完整计数更快。
我也切断了中间人。加入task_list
只会确定task_list
中的相关行存在 - 这样会浪费时间:
task
中始终存在task_list
。
理想情况下使用FK约束实现强制参照完整性。 如果没有实际的表格定义,我必须做出有根据的猜测。
要为任何表格大小设置 fast ,您需要3个btree(默认)索引
task(uid, task_list_uid)
task_list_assignee(task_list_uid)
task_list_sharee(task_list_uid)
答案 1 :(得分:0)
如果以Task作为基表开始并执行一系列左连接,您应该能够使用coalesce确定哪些任务具有受理人和sharee的值:
select count(*)
from task as t
left join
task_list as l
on t.task_list_uid = l.uid
left join
task_list_assignee as a
on l.uid = a.task_list_uid
left join
task_list_sharee as s
on l.uid = s.task_list_uid
where coalesce( a.task_list_uid, s.task_list_uid ) is not null
and t.uid = ?
SQL小提琴here