我有一个查询,需要超过2小时来执行百万条记录,我不知道如何优化它以使其运行速度更快。 Here是表和查询的sql小提琴。
WITH frm
AS (SELECT product_id AS PId,
Min(Cast(product_startdate AS DATETIME)) AS PStartDate
FROM products
WHERE product_status IN ( 'F', 'R', 'M' )
GROUP BY product_id),
firstcount
AS (SELECT pid,
pstartdate,
(SELECT Count(*)
FROM products
WHERE product_id IN ((SELECT product_id
FROM products
WHERE product_status IN ( 'OR', 'OP' )
AND product_comments LIKE
'%CANCELLED%'
EXCEPT
(SELECT product_id
FROM products
WHERE product_status = 'DE'
UNION
SELECT product_id
FROM products
WHERE product_status = 'OR'
AND product_comments NOT LIKE
'%CANCELLED%'))
EXCEPT
(SELECT product_id
FROM products
WHERE product_status IN (
'RE', 'C', 'S', 'D' )
))
AND product_id = pid) AS v_count
FROM frm),
secondcount
AS (SELECT pid,
pstartdate,
CASE
WHEN v_count = 0 THEN (SELECT Count(*)
FROM products
WHERE product_id IN
(
SELECT product_id
FROM [dbo].products
WHERE
product_status IN ( 'F',
'R', 'M' )
AND product_startdate !=
'.'
EXCEPT
(SELECT
product_id
FROM products
WHERE
product_status = 'DE'
UNION
SELECT
product_id
FROM products
WHERE
product_status = 'OR'
AND product_comments NOT
LIKE '%CANCELLED%')
EXCEPT
(SELECT
product_id
FROM products
WHERE
product_status IN ( 'OR',
'OP' )
AND product_comments LIKE
'%CANCELLED%'
EXCEPT
(SELECT
product_id
FROM products
WHERE
product_status =
'DE'
UNION
SELECT product_id
FROM products
WHERE product_status =
'OR'
AND product_comments NOT
LIKE '%CANCELLED%'))
EXCEPT
(SELECT
product_id
FROM products
WHERE
product_status IN ( 'RE',
'C', 'S', 'D' )))
AND product_id = pid)
ELSE v_count
END AS v_count
FROM firstcount)
INSERT INTO products_del
(product_id,
product_startdate,
productdel_status)
SELECT pid,
pstartdate,
CASE
WHEN v_count != 0 THEN 'UNKNOWN'
ELSE NULL
END
FROM secondcount
SELECT *
FROM products_del
答案 0 :(得分:1)
请尝试以下方法。我通过删除不必要的IN
,UNION
和EXCEPT
子句来简化内部查询。
WITH frm
AS (SELECT product_id AS PId,
Min(Cast(product_startdate AS DATETIME)) AS PStartDate
FROM products
WHERE product_status IN ( 'F', 'R', 'M' )
GROUP BY product_id),
firstcount
AS (SELECT pid,
pstartdate,
(SELECT Count(*)
FROM products
WHERE product_status IN ( 'OR', 'OP' )
AND product_comments LIKE '%CANCELLED%'
AND product_id = pid) AS v_count
FROM frm),
secondcount
AS (SELECT pid,
pstartdate,
CASE
WHEN v_count = 0 THEN (SELECT Count(*)
FROM products
WHERE product_status IN ( 'F', 'R', 'M' )
AND product_startdate != '.'
AND product_id = pid)
ELSE v_count
END AS v_count
FROM firstcount)
INSERT INTO products_del
(product_id,
product_startdate,
productdel_status)
SELECT pid,
pstartdate,
CASE
WHEN v_count != 0 THEN 'UNKNOWN'
ELSE NULL
END
FROM secondcount
SELECT *
FROM products_del