我有一个运行速度非常慢的sql视图。您能否通过一些指示来了解我如何查看查询的哪些部分花费最多时间。
以下查询
CREATE view ConsolidationReportView
as
SELECT distinct TOP (100) PERCENT
Client.OH_Code AS ClientCode,
client.OH_FullName AS Client,
consignee.OH_Code AS ConsigneeCode,
CASE WHEN consignee.oh_pk IS NULL THEN consigneedocaddress.e2_companyname ELSE consignee.oh_fullname END AS Consignee,
RefCountry_1.RN_Desc AS CGNEE_COUNTRY,
dbo.Client_ReturnWK(pallet.MB_PR_CLOSED_DT) AS WEEKNUM,
part.OP_Desc AS ProductDescription,
part.OP_CustomAttrib1 AS ISSUE_DESC,
part.OP_Weight AS x,
ROUND(part.OP_Weight * packing.MB_PD_Units + .5, 0) AS Weight,
packing.MB_PD_Units AS Units,
CASE WHEN RS_Description = 'AIR' OR RS_Description = 'SEA' THEN 0 ELSE .03 END AS Rate,
CASE WHEN RS_Description = 'AIR' OR RS_Description = 'SEA' THEN 0 ELSE .03 END *
ROUND(part.OP_Weight * packing.MB_PD_Units + .5, 0) AS Charge,
docket.WD_DocketID,
CASE WHEN RS_Description = 'Warehouse Handling' THEN 'HAN' ELSE RS_description END AS Service,
'NO AUTO/R.' AS CHARGE_SELL_AMMOUNT,
docket.WD_DocketStatus AS DOCKET_STATUS,
OrgMiscServ.OM_CustomFlag2 AS SHIP_ACCOUNT,
'' AS INVOICE_NUM,
part.OP_Desc AS TITLE,
CASE WHEN OU_LocalPartNumber IS NULL THEN CASE WHEN LEN(SUBSTRING(part.OP_PartNum, 1, CASE WHEN CHARINDEX('-',
part.OP_PartNum) > 0 THEN CHARINDEX('-', part.OP_PartNum) - 1 ELSE 0 END)) = 0 THEN OU_LocalPartNumber ELSE SUBSTRING(part.OP_PartNum, 1,
CASE WHEN CHARINDEX('-', part.OP_PartNum) > 0 THEN CHARINDEX('-', part.OP_PartNum) - 1 ELSE 0 END) END ELSE OU_LocalPartNumber END AS MAG_CODE,
client.OH_PK AS ClientPK,
warehouse.WW_PK AS WarehousePK,
docketline.WE_OP AS ProductPK,
pallet.MB_PR_CLOSED_DT,
part.OP_Weight AS COPY_KG,
CASE WHEN RS_Description = 'AIR' OR RS_Description = 'SEA' THEN 0 ELSE dbo.Client_ReturnTariffCharge(client.OH_PK,
pallet.MB_PR_CLOSED_DT, 'WHSHAN', part.OP_Weight, packing.MB_PD_Units) END AS TARIFF_CHRG,
CASE WHEN RS_Description = 'AIR' OR RS_Description = 'SEA' THEN 0 ELSE dbo.Client_ReturnTariffRate(client.OH_PK, pallet.MB_PR_CLOSED_DT, 'WHSHAN') END AS TARIFF_RATE,
DATEPART(YEAR, CONVERT(varchar(8), pallet.MB_PR_CLOSED_DT, 112)) AS YEAR,
CASE WHEN RS_Description = 'AIR' OR RS_Description = 'SEA' THEN 0 ELSE dbo.Client_ReturnTariffCharge(client.OH_PK,
pallet.MB_PR_CLOSED_DT, 'WHSHAN', part.OP_Weight + .009, packing.MB_PD_Units) END AS TARIFF_CHRG_UPLIFT,
(part.OP_Weight + .009) * packing.MB_PD_Units AS Weight_UPLIFT,
part.OP_Weight + .009 AS COPY_KG_UPLIFT
FROM
Client_whspalletpacking packing WITH (NOLOCK)
inner join whsDocketLine docketLine WITH (NOLOCK) on packing.we_fk =docketline.we_pk
inner join whsDocket docket WITH (NOLOCK) on docketline.we_wd =docket.wd_pk
inner join client_whspallet pallet WITH (NOLOCK) on packing.MB_PD_PR = pallet.MB_PR_PK
inner join orgheader Client WITH (NOLOCK) on docket.wd_oh_client= Client.oh_pk
inner join orgheader consignee WITH (NOLOCK) on packing.MB_PR_OH=consignee.oh_pk
INNER JOIN OrgSupplierPart part WITH (NOLOCK) ON docketline.WE_OP = part.OP_PK
left outer join OrgPartRelation WITH (NOLOCK) on part.op_pk=OrgPartRelation.OU_OP
inner join OrgMiscServ WITH (NOLOCK) on consignee.OH_PK =OrgMiscServ.OM_OH
inner join JobDocAddress AS consigneedocaddress WITH (NOLOCK) on docket.WD_PK=consigneedocaddress.E2_ParentID
INNER JOIN RefUNLOCO AS RefUNLOCO_1 WITH (NOLOCK) ON consignee.OH_RL_NKClosestPort = RefUNLOCO_1.RL_Code
INNER JOIN RefCountry AS RefCountry_1 WITH (NOLOCK) ON RefUNLOCO_1.RL_RN = RefCountry_1.RN_PK
INNER JOIN WhsWarehouse AS warehouse WITH (NOLOCK) ON warehouse.WW_PK = docket.WD_WW_Whs
inner join RefServiceLevel WITH (NOLOCK) on docket.WD_RS_ServiceLevel = RefServiceLevel.RS_PK
ORDER BY
part.OP_Desc ,
part.OP_CustomAttrib1,
CASE WHEN consignee.oh_pk IS NULL THEN consigneedocaddress.e2_companyname ELSE consignee.oh_fullname END,
RefCountry_1.RN_Desc
由于
答案 0 :(得分:3)
尝试查看其查询执行 计划。
使用DMV
查找缺失的索引。
运行sql profiler查看获取的锁数是否过多。
运行查询时检查服务器运行状况。
您可以通过
清理查询结果缓冲区DBCC DROPCLEANBUFFERS 开始强>
像这样运行您的视图并进入消息标签
设置统计时间 设置统计信息 转到
从youview中选择*
设置统计信息关闭 走 设置统计时间 转到
DBCC DROPCLEANBUFFERS gO的
查看您的查询是否属于其中一个或两者的结果集。
- 按逻辑读取(内存压力)排序前200名执行的SP
SELECT TOP 200 qt.text AS 'SP Name', total_logical_reads,
qs.execution_count AS 'Execution Count', total_logical_reads/qs.execution_count AS 'AvgLogicalReads',
qs.execution_count/DATEDIFF(Second, qs.creation_time, GetDate()) AS 'Calls/Second',
qs.total_worker_time/qs.execution_count AS 'AvgWorkerTime',
qs.total_worker_time AS 'TotalWorkerTime',
qs.total_elapsed_time/qs.execution_count AS 'AvgElapsedTime',
qs.total_logical_writes,
qs.max_logical_reads, qs.max_logical_writes, qs.total_physical_reads,
DATEDIFF(Minute, qs.creation_time, GetDate()) AS 'Age in Cache', qt.dbid
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt
WHERE qt.dbid = db_id() -- Filter by current database
ORDER BY total_logical_reads DESC
- 按总工时(CPU压力)排序前20名执行SP
SELECT TOP 200 qt.text AS 'SP Name', qs.total_worker_time AS 'TotalWorkerTime',
qs.total_worker_time/qs.execution_count AS 'AvgWorkerTime',
qs.execution_count AS 'Execution Count',
ISNULL(qs.execution_count/DATEDIFF(Second, qs.creation_time, GetDate()), 0) AS 'Calls/Second',
ISNULL(qs.total_elapsed_time/qs.execution_count, 0) AS 'AvgElapsedTime',
qs.max_logical_reads, qs.max_logical_writes,
DATEDIFF(Minute, qs.creation_time, GetDate()) AS 'Age in Cache'
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt
WHERE qt.dbid = db_id() -- Filter by current database
ORDER BY qs.total_worker_time DESC
答案 1 :(得分:1)
这些连接是否偶然引用了其他视图?如果您想要表现,请不要在视图中引用视图。
这也是罪魁祸首的好机会 dbo.Client_ReturnWK(pallet.MB_PR_CLOSED_DT)
以这种方式使用的函数经常强制逐行而不是基于集合的处理,并极大地减慢查询速度。
答案 2 :(得分:0)
取决于查询。
首先尝试解释计划。
答案 3 :(得分:0)
正如其他人所说,你需要看一下执行计划。如果这是MS SQL并且您对此不熟悉,则可以找到更多详细信息here。还有一个链接,您可以免费下载完整的电子书。