您好我有一个存储过程
ALTER PROCEDURE [dbo].[usp_EP_GetTherapeuticalALternates]
(
@NDCNumber CHAR(11) ,
@patientid INT ,
@pbmid INT
)
AS
BEGIN
TRUNCATE TABLE TempTherapeuticAlt
INSERT INTO TempTherapeuticAlt
SELECT --PR.ProductID AS MedicationID ,
NULL AS MedicationID ,
PR.ePrescribingName AS MedicationName ,
U.Strength AS MedicationStrength ,
FRM.FormName AS MedicationForm ,
PR.DEAClassificationID AS DEASchedule ,
NULL AS NDCNumber
--INTO #myTemp
FROM DatabaseTwo.dbo.Product PR
JOIN ( SELECT MP.MarketedProductID
FROM DatabaseTwo.dbo.Therapeutic_Concept_Tree_Specific_Product TCTSP
JOIN DatabaseTwo.dbo.Marketed_Product MP ON MP.SpecificProductID = TCTSP.SpecificProductID
JOIN ( SELECT TCTSP.TherapeuticConceptTreeID
FROM DatabaseTwo.dbo.Marketed_Product MP
JOIN DatabaseTwo.dbo.Therapeutic_Concept_Tree_Specific_Product TCTSP ON MP.SpecificProductID = TCTSP.SpecificProductID
JOIN ( SELECT
PR.MarketedProductID
FROM
DatabaseTwo.dbo.Package PA
JOIN DatabaseTwo.dbo.Product PR ON PA.ProductID = PR.ProductID
WHERE
PA.NDC11 = @NDCNumber
) PAPA ON MP.MarketedProductID = PAPA.MarketedProductID
) xxx ON TCTSP.TherapeuticConceptTreeID = xxx.TherapeuticConceptTreeID
) MPI ON PR.MarketedProductID = MPI.MarketedProductID
JOIN ( SELECT P.ProductID ,
O.Strength ,
O.Unit
FROM DatabaseTwo.dbo.Product AS P
INNER JOIN DatabaseTwo.dbo.Marketed_Product
AS M ON P.MarketedProductID = M.MarketedProductID
INNER JOIN DatabaseTwo.dbo.Specific_Product
AS S ON M.SpecificProductID = S.SpecificProductID
LEFT OUTER JOIN DatabaseTwo.dbo.OrderableName_Combined
AS O ON S.SpecificProductID = O.SpecificProductID
GROUP BY P.ProductID ,
O.Strength ,
O.Unit
) U ON PR.ProductID = U.ProductID
JOIN ( SELECT PA.ProductID ,
S.ScriptFormID ,
F.Code AS NCPDPScriptFormCode ,
S.FormName
FROM DatabaseTwo.dbo.Package AS PA
INNER JOIN DatabaseTwo.dbo.Script_Form
AS S ON PA.NCPDPScriptFormCode = S.NCPDPScriptFormCode
INNER JOIN DatabaseTwo.dbo.FormCode AS F ON S.FormName = F.FormName
GROUP BY PA.ProductID ,
S.ScriptFormID ,
F.Code ,
S.FormName
) FRM ON PR.ProductID = FRM.ProductID
WHERE
( PR.OffMarketDate IS NULL )
OR ( PR.OffMarketDate = '' )
OR (PR.OffMarketDate = '1899-12-30 00:00:00.000')
OR ( PR.OffMarketDate <> '1899-12-30 00:00:00.000'
AND DATEDIFF(dd, GETDATE(),PR.OffMarketDate) > 0
)
GROUP BY PR.ePrescribingName ,
U.Strength ,
FRM.FormName ,
PR.DEAClassificationID
-- ORDER BY pr.ePrescribingName
SELECT LL.ProductID AS MedicationID ,
temp.MedicationName ,
temp.MedicationStrength ,
temp.MedicationForm ,
temp.DEASchedule ,
temp.NDCNumber ,
fs.[ReturnFormulary] AS FormularyStatus ,
copay.CopaTier ,
copay.FirstCopayTerm ,
copay.FlatCopayAmount ,
copay.PercentageCopay ,
copay.PharmacyType,
dbo.udf_EP_GetBrandGeneric(LL.ProductID) AS BrandGeneric
FROM TempTherapeuticAlt temp
OUTER APPLY ( SELECT TOP 1
ProductID
FROM DatabaseTwo.dbo.Product
WHERE ePrescribingName = temp.MedicationName
) AS LL
OUTER APPLY [dbo].[udf_EP_tbfGetFormularyStatus](@patientid,
LL.ProductID,
@pbmid) AS fs
OUTER APPLY ( SELECT TOP 1
*
FROM udf_EP_CopayDetails(LL.ProductID,
@PBMID,
fs.ReturnFormulary)
) copay
--ORDER BY LL.ProductID
TRUNCATE TABLE TempTherapeuticAlt
END
在我的开发服务器上,我在每个表中都有63k的数据
所以这个过程大约需要30秒才能返回结果。
在我的生产服务器上,它超时,或者花费> 1分钟。 我想知道我的生产服务器表已满了1400万条记录,
这可能是一个原因。
如果是这样,可以做什么,我在表上都需要索引。
任何帮助将不胜感激。
感谢
执行计划 http://www.sendspace.com/file/hk8fao
OUTER APPLY [dbo].[udf_EP_tbfGetFormularyStatus](@patientid,
LL.ProductID,
@pbmid) AS fs
答案 0 :(得分:4)
一些可能有用的策略:
删除第一个ORDER BY语句,这些都是复杂查询的杀手锏。
使用CTE将查询分解为可以单独处理的较小部分。
减少第一组JOIN中的嵌套
提取第二组和第三组连接(GROUPED连接),并在连接和分组所有内容之前将它们插入临时索引表中。
您未包含function1
或function2
的定义 - 自定义函数通常是性能问题可隐藏的地方。
如果没有看到执行计划,很难看出特定问题可能在哪里。
答案 1 :(得分:3)
您有一个查询从4或5个表中选择数据,其中一些表多次。如果不深入分析你想要实现的目标以及实际上是什么表结构,很难说如何改进。
数据大小肯定是个问题;我认为很明显,必须处理的数据越多,查询所需的时间就越长。一些一般性建议...直接运行查询并检查执行计划。它可能揭示瓶颈。然后检查统计数据是否是最新的。此外,检查您的表,在某些情况下,分区可能会有很大帮助。此外,您可以尝试更改表并在PK上创建聚簇索引(除非另有指定,否则默认情况下已完成),但在其他列[s]上,因此您的查询将受益于某些物理记录顺序。注意:只有在你完全确定自己在做什么的情况下才能这样做。
最后,尝试重构您的查询。我有一种感觉,有更好的方法来获得理想的结果(对不起,没有理解表结构和预期结果我不能说出确切的解决方案,但是同一个表和一堆派生表的多个连接对我来说不太好看)