我从旧版应用程序获得以下查询,而在执行此查询时,它花费了太多时间进行响应。因此,我打算将这个复杂的查询分解为多个查询,并在应用程序端(即较新的应用程序)中执行一些操作。
WITH members AS (
SELECT
shift_group_code,
shift_code,
0 AS isCycle,
CHAR(10) + CAST(shift_group_code AS varchar(max)) + CHAR(10) AS [path]
FROM shift_grouping
WHERE workspace_code IN ('default', 'test', 'test1')
AND shift_group_code = 'WS+DEFAULT'
UNION
ALL
SELECT
H.shift_group_code,
H.shift_code,
CASE
WHEN M.[path] LIKE '%' + CHAR(10) + CAST(H.shift_code AS varchar(max)) + CHAR(10) + '%'
THEN 1
ELSE 0
END AS isCycle,
M.[path] + CAST(H.shift_code AS varchar(max)) + CHAR(10) AS [path]
FROM
shift_grouping H
JOIN
members M
ON H.shift_group_code = M.shift_code
AND M.shift_code IN (SELECT
code
FROM
shift_group)
WHERE
H.workspace_code IN ('default', 'test', 'test1')
AND M.isCycle = 0)
SELECT
*
FROM shift
WHERE
workspace_code IN (
'default', 'test', 'test1'
)
AND (
code = 'WS+DEFAULT'
OR code IN (
SELECT
DISTINCT shift_code
FROM
members
WHERE
isCycle = 0
)
)
我可以在UNION
之前破坏第一部分
即
SELECT shift_group_code, shift_code,
0 AS isCycle,
CHAR(10) + CAST(shift_group_code AS varchar(max)) + CHAR(10) AS [path]
FROM shift_grouping
WHERE workspace_code IN ('default', 'test', 'test1')
AND shift_group_code = 'WS+DEFAULT'
但是查询的第二部分
SELECT H.shift_group_code, H.shift_code,
CASE
WHEN M.[path] LIKE '%' + CHAR(10) + CAST(H.shift_code AS varchar(max)) + CHAR(10) + '%'
THEN 1
ELSE 0
END AS isCycle,
M.[path] + CAST(H.shift_code AS varchar(max)) + CHAR(10) AS [path]
FROM shift_grouping H
JOIN members M
ON H.shift_group_code = M.shift_code
AND M.shift_code IN (SELECT code FROM shift_group)
WHERE H.workspace_code IN ('default', 'test', 'test1')
我无法中断,因为有一个JOIN members M
语句不允许我中断SQL。
members
来自较大查询开始时的WITH members
语句。
或者我无法理解他们如何将members
与shift_grouping
结合在一起。
有人可以为我打断此查询吗?
答案 0 :(得分:1)
在没有更多有关数据库模式的知识的情况下,很难优化该查询,但是它可以帮助您了解其运行情况。
我还用IN条件替换了EXISTS,它将为您提供更好的性能,但我认为这还不够
成员是公用表表达式(CTE),当调用它本身称为递归CTE时,它定义了一个临时结果集。
SHIFT_GROUPING似乎是您的层次结构表,因此,第一个SELECT语句定义CTE的起始位置,UNION ALL之后的SELECT定义迭代
通常,递归CTE包含三个部分:
递归CTE的执行顺序如下:
第三,使用UNION ALL运算符组合所有结果集R0,R1,... Rn,以产生最终结果集。
;WITH members AS --CTE Declaration
(
-- Defines the initial query of the CTE
SELECT
shift_group_code,
shift_code,
0 AS isCycle,
CHAR(10) + CAST(shift_group_code AS varchar(max)) + CHAR(10) AS [path]
FROM shift_grouping
WHERE workspace_code IN ('default', 'test', 'test1')
AND shift_group_code = 'WS+DEFAULT'
UNION ALL
-- Recursive query that references [members]
SELECT
H.shift_group_code,
H.shift_code,
CASE
WHEN M.[path] LIKE '%' + CHAR(10) + CAST(H.shift_code AS varchar(max)) + CHAR(10) + '%'
THEN 1
ELSE 0
END AS isCycle,
M.[path] + CAST(H.shift_code AS varchar(max)) + CHAR(10) AS [path]
FROM
shift_grouping H
JOIN
members M ON H.shift_group_code = M.shift_code -- In this case, the join acts as the termination condition
WHERE
H.workspace_code IN ('default', 'test', 'test1')
AND M.isCycle = 0
AND EXISTS (SELECT 1 FROM shift_group WHERE code = M.shift_code)
)
SELECT *
FROM shift S
WHERE
workspace_code IN ('default', 'test', 'test1')
AND (
code = 'WS+DEFAULT'
OR EXISTS (
SELECT 1
FROM
members
WHERE
isCycle = 0 AND shift_code = S.code
)
)