CTE查询与类似代码的性能差异

时间:2017-04-10 22:20:42

标签: sql-server tsql sql-server-2012 query-performance

我正在寻求基于标准/最佳实践的查询性能分析。欢迎使用任何重写或输入来优化我的代码。

我使用基于SQL服务器的基于Web的工具来查询我只有执行权限的数据库。没有SSMS环境来分析查询计划。我试图找出两组相似代码之间背后的性能差异的原因。我已从SELECT语句中删除了一些对两者都相同的其他字段,这些字段会同等地影响性能。此外,由于外部限制,我CONVERTING已将datetime投放回CASE

案例1:带有计算的重复和详细JOIN语句。没有额外的CTE因此少了DateCTE

案例2:使用额外的WITH CTE AS (SELECT C.client_id AS [Client ID] ,CAST(CV.date1 AS DATE) AS SDate ,VT.label AS Service ,MIN(CASE WHEN VT.label='A' THEN CAST(CV.date1 AS DATE) END) OVER (PARTITION BY C.client_id) AS [FirstAssist Date] ,CI.billing_ord AS Ord FROM C INNER JOIN CV ON C.client_id=CV.client_id LEFT JOIN VT ON VT.visittype_id=CV.visittype_id LEFT JOIN CI ON CI.client_id=C.client_id ) SELECT DISTINCT CTE.[Client ID] ,CONVERT(datetime,COALESCE(MIN(CASE WHEN CTE.Service LIKE '%med%' AND CTE.SDate >= CTE.FirstAssistDate THEN CTE.SDate END) OVER (PARTITION BY CTE.[Client ID]) ,CASE WHEN DATEDIFF(day,CTE.FirstAssistDate, MIN(CASE WHEN CTE.Service LIKE '%med%' THEN CTE.SDate END) OVER (PARTITION BY CTE.[Client ID])) >=-5 THEN MIN(CASE WHEN CTE.Service LIKE '%med%' THEN CTE.SDate END) OVER (PARTITION BY CTE.[Client ID]) END)) AS [Start Date] ,COALESCE(DATEDIFF(day, CTE.[FirstAssist Date], MIN(CASE WHEN CTE.Service LIKE '%med%eval%' AND CTE.SDate >= CTE.[FirstAssist Date] THEN CTE.SDate END) OVER (PARTITION BY CTE.[Client ID])) ,CASE WHEN DATEDIFF(day, CTE.[FirstAssist Date], MIN(CASE WHEN CTE.Service LIKE '%med%eval%' THEN CTE.SDate END) OVER (PARTITION BY CTE.[Client ID])) >= -5 THEN ABS(DATEDIFF(day, CTE.[FirstAssist Date], MIN(CASE WHEN CTE.Service LIKE '%med%eval%' THEN CTE.SDate END) OVER (PARTITION BY CTE.[Client ID]))) END) AS [Days to Treat] FROM CTE INNER JOIN (SELECT CTE.[Client ID], MIN(CTE.Ord) AS MinOrd FROM CTE GROUP BY CTE.[Client ID]) InsCTE ON CTE.[Client ID]=InsCTE.[Client ID] AND CTE.[Ord]=InsCTE.MinOrd WHERE 1=1 AND CTE.[Client ID] NOT IN (SELECT [Client ID] FROM CTE WHERE Service LIKE 'B') AND CTE.SDate BETWEEN '20150701' AND '20170301' 缩短了别名,导致额外的JOIN

目前,案例2的执行时间比案例1

长4-5倍

第1集代码:

WITH CTE AS
(SELECT
    C.client_id AS [Client ID]
    ,CAST(CV.date1 AS DATE) AS SDate
    ,VT.label AS Service
    ,MIN(CASE WHEN VT.label='A' THEN CAST(CV.date1 AS DATE) END) OVER (PARTITION BY C.client_id) AS [FirstAssist Date]
    ,CI.billing_ord AS Ord

FROM C
INNER JOIN CV
    ON C.client_id=CV.client_id
LEFT JOIN VT
    ON VT.visittype_id=CV.visittype_id
LEFT JOIN CI
    ON CI.client_id=C.client_id
)
,DateCTE AS
(SELECT
     [Client ID] 
    ,MIN(CASE WHEN CTE.Service LIKE '%med%eval%' THEN CTE.SDate END) OVER (PARTITION BY CTE.[Client ID]) AS MedEvalDate
    ,MIN(CASE WHEN CTE.Service LIKE '%med%eval%' AND CTE.SDate >= CTE.FirstAssistDate THEN CTE.SDate END) OVER (PARTITION BY CTE.[Client ID]) AS FirstMedEvalDate
    ,MIN(CASE WHEN CTE.Service LIKE '%med%' THEN CTE.SDate END) OVER (PARTITION BY CTE.[Client ID]) AS MedSvcDate
    ,MIN(CASE WHEN CTE.Service LIKE '%med%' AND CTE.SDate >= CTE.FirstAssistDate THEN CTE.SDate END) OVER (PARTITION BY CTE.[Client ID]) AS FirstMedSvcDate
  FROM CTE
)

SELECT DISTINCT
    CTE.[Client ID]
    ,CONVERT(datetime,COALESCE(DateCTE.FirstMedSvcDate,CASE WHEN DATEDIFF(day,CTE.FirstAssistDate, DateCTE.MedSvcDate) >=-5 THEN DateCTE.MedSvcDate END)) AS [Start Date]
    ,COALESCE(DATEDIFF(day, CTE.FirstAssistDate, DateCTE.FirstMedEvalDate),CASE WHEN DATEDIFF(day, CTE.FirstAssistDate, DateCTE.MedEvalDate) >= -5
        THEN ABS(DATEDIFF(day, CTE.FirstAssistDate, DateCTE.MedEvalDate))END) 
    AS [Days to Treat]

FROM CTE
INNER JOIN (SELECT CTE.[Client ID], MIN(CTE.Ord) AS MinOrd FROM CTE GROUP BY CTE.[Client ID]) InsCTE ON CTE.[Client ID]=InsCTE.[Client ID] AND CTE.[Ord]=InsCTE.MinOrd
INNER JOIN DateCTE ON CTE.[Client ID]=DateCTE.[Client ID]
WHERE 1=1
    AND CTE.[Client ID] NOT IN (SELECT [Client ID] FROM CTE WHERE Service LIKE 'B')
    AND CTE.SDate BETWEEN '20150701' AND '20170301'

第2集代码:

import csv

date = []

open_price = []

high = []

low = []

close = []

volume = []

adj_close = []


with open(r'C:\Users\bruno.rojas\Desktop\Python_Data\SPX_Prices.csv') as f:

    reader = csv.reader(f)

    for row in reader:
        date.append(row[0])
        open_price.append(row[1])
        high.append(row[2])
        low.append(row[3])
        close.append(row[4])
        volume.append(row[5])
        adj_close.append(row[6])
date = str(date).encode()
open_price = open_price
open_prices = dict(zip(date, open_price))
high_prices = dict(zip(date, high))
low_prices = dict(zip(date, low))

close_prices = dict(zip(date,close))
volume_prices = dict(zip(date, volume))
adj_close_prices = dict(zip(date, adj_close))
with open('output.csv', 'wb') as output:
    writer = csv.writer(output)
    writer.writerow(date)

0 个答案:

没有答案