使这个查询更快
Making this query faster
因此,正如我之前提到的,我不处理原始的 SQL,因为它们通常需要帮助来增强此查询。目前,大约需要 3 秒。我想知道他们是否有办法让它变得更好。我删除了一些选择以使查询更小。
select row_number() over () as id,
scope.id as sow_id,
scope.*,
task.*,
po.entity_id as group_name
from t_scope_of_work as scope,
(select * from audittaskimpl) as task
Left join peopleassignments_potowners po ON task.taskid = po.task_id and po.entity_id like '%/%'
Where task.processinstanceid IN
(select distinct processinstanceid from taskvariableimpl where value = scope.sownumber)
order by task.processinstanceid desc, task.createdon desc;
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|QUERY PLAN |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|Sort (cost=3037398.97..3037728.28 rows=131726 width=1981) (actual time=1714.744..1714.812 rows=648 loops=1) |
| Sort Key: task.processinstanceid DESC, task.createdon DESC |
| Sort Method: quicksort Memory: 884kB |
| Buffers: shared hit=930703 |
| -> WindowAgg (cost=0.55..2800174.53 rows=131726 width=1981) (actual time=6.919..1713.339 rows=648 loops=1) |
| Buffers: shared hit=930703 |
| -> Merge Right Join (cost=0.55..2798527.96 rows=131726 width=1965) (actual time=6.905..1712.235 rows=648 loops=1) |
| Merge Cond: (po.task_id = task.taskid) |
| Buffers: shared hit=930703 |
| -> Index Only Scan using idx_paspot_taskentity on peopleassignments_potowners po (cost=0.27..32.45 rows=462 width=28) (actual time=0.101..0.378 rows=446 loops=1)|
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
您的查询归结为:
select row_number() over () as id,
scope.id as sow_id,
scope.*,
task.*,
po.entity_id as group_name
from t_scope_of_work as scope
join audittaskimpl as task
on task.processinstanceid IN (select distinct tvi.processinstanceid
from taskvariableimpl tvi
where tvi.value = scope.sownumber)
Left outer join peopleassignments_potowners po
ON po.task_id = task.taskid
and po.entity_id like '%/%'
order by task.processinstanceid desc, task.createdon desc;
如果没有解释,几乎不可能就此查询中的瓶颈所在提出建议。例如。您可能缺少一些索引,可能只是因为数据太多而无法快速获取。
就是说,我怀疑您是否需要其中的 distinct
;事实上,可能值得尝试 EXISTS()
构造,只是为了看看它给出了什么。
像这样:
select row_number() over () as id,
scope.id as sow_id,
scope.*,
task.*,
po.entity_id as group_name
from t_scope_of_work as scope
join audittaskimpl as task
on exists ( select *
from taskvariableimpl tvi
where tvi.value = scope.sownumber
and tvi.processinstanceid = task.processinstanceid )
Left outer join peopleassignments_potowners po
ON po.task_id = task.taskid
and po.entity_id like '%/%'
order by task.processinstanceid desc, task.createdon desc;
警告:先试后买!这可能比您原来的查询更有效,我以前从未做过 JOIN [..] ON EXISTS()
;再次,如果不正确了解您的表、卷、索引、数据布局(阅读:连接中有很多 'hits' 还是只有几条记录?),等等......我们在这里几乎是在盲目工作。
因此,正如我之前提到的,我不处理原始的 SQL,因为它们通常需要帮助来增强此查询。目前,大约需要 3 秒。我想知道他们是否有办法让它变得更好。我删除了一些选择以使查询更小。
select row_number() over () as id,
scope.id as sow_id,
scope.*,
task.*,
po.entity_id as group_name
from t_scope_of_work as scope,
(select * from audittaskimpl) as task
Left join peopleassignments_potowners po ON task.taskid = po.task_id and po.entity_id like '%/%'
Where task.processinstanceid IN
(select distinct processinstanceid from taskvariableimpl where value = scope.sownumber)
order by task.processinstanceid desc, task.createdon desc;
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|QUERY PLAN |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|Sort (cost=3037398.97..3037728.28 rows=131726 width=1981) (actual time=1714.744..1714.812 rows=648 loops=1) |
| Sort Key: task.processinstanceid DESC, task.createdon DESC |
| Sort Method: quicksort Memory: 884kB |
| Buffers: shared hit=930703 |
| -> WindowAgg (cost=0.55..2800174.53 rows=131726 width=1981) (actual time=6.919..1713.339 rows=648 loops=1) |
| Buffers: shared hit=930703 |
| -> Merge Right Join (cost=0.55..2798527.96 rows=131726 width=1965) (actual time=6.905..1712.235 rows=648 loops=1) |
| Merge Cond: (po.task_id = task.taskid) |
| Buffers: shared hit=930703 |
| -> Index Only Scan using idx_paspot_taskentity on peopleassignments_potowners po (cost=0.27..32.45 rows=462 width=28) (actual time=0.101..0.378 rows=446 loops=1)|
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
您的查询归结为:
select row_number() over () as id,
scope.id as sow_id,
scope.*,
task.*,
po.entity_id as group_name
from t_scope_of_work as scope
join audittaskimpl as task
on task.processinstanceid IN (select distinct tvi.processinstanceid
from taskvariableimpl tvi
where tvi.value = scope.sownumber)
Left outer join peopleassignments_potowners po
ON po.task_id = task.taskid
and po.entity_id like '%/%'
order by task.processinstanceid desc, task.createdon desc;
如果没有解释,几乎不可能就此查询中的瓶颈所在提出建议。例如。您可能缺少一些索引,可能只是因为数据太多而无法快速获取。
就是说,我怀疑您是否需要其中的 distinct
;事实上,可能值得尝试 EXISTS()
构造,只是为了看看它给出了什么。
像这样:
select row_number() over () as id,
scope.id as sow_id,
scope.*,
task.*,
po.entity_id as group_name
from t_scope_of_work as scope
join audittaskimpl as task
on exists ( select *
from taskvariableimpl tvi
where tvi.value = scope.sownumber
and tvi.processinstanceid = task.processinstanceid )
Left outer join peopleassignments_potowners po
ON po.task_id = task.taskid
and po.entity_id like '%/%'
order by task.processinstanceid desc, task.createdon desc;
警告:先试后买!这可能比您原来的查询更有效,我以前从未做过 JOIN [..] ON EXISTS()
;再次,如果不正确了解您的表、卷、索引、数据布局(阅读:连接中有很多 'hits' 还是只有几条记录?),等等......我们在这里几乎是在盲目工作。