我正在处理的应用程序生成一个SQL查询,如下所示:
Select
VISIT_VIEW.VISIT_ID, VISIT_VIEW.PATIENT_ID, VISIT_VIEW.MRN_ID,
VISIT_VIEW.BILL_NO, INSURANCE.INS_PAYOR'
FROM
'VISIT_VIEW
LEFT JOIN
INSURANCE ON VISIT_VIEW.visit_id = INSURANCE._fk_visit '
WHERE
'VISIT_VIEW.VISIT_ID IN (1002, 1003, 1005, 1006, 1007, 1008, 1010, 1011, <...>, 1193, 1194, 1195, 1196, 1197, 1198, 1199)'
<...>
表示一长串ID。列表的大小取决于先前查询的结果,进而取决于选择用于生成该查询的参数。
ID列表可以是从100项到2000以上的任何地方。
INSURANCE
表很大,超过900万行。访问表也很大,但不是很大。
随着身份证数量的增加,从不到一秒的持续时间到超过15分钟的数量会有相当大的增长。增长开始大约175 ids。
如果更改了用于生成查询的参数,以便未选择INS_PAYOR
列,因此没有左连接,则查询在不到一秒的时间内运行,即使在超过2000个项目中也是如此ID列表。
执行计划显示97%的查询时间用于INSURANCE
表上的集群搜索。
如何以较少可怕的延迟重新设计此查询以获得相同的结果?
请记住,SQL是由代码生成的,而不是手工生成的。它是从字段列表(知道哪个字段属于哪个表)和要检查的主表中的ID列表生成的。我可以访问执行查询生成的代码,并且可以更改它,前提是查询的最终结果完全相同。
谢谢
答案 0 :(得分:0)
&lt; ...&gt;代表一长串的ID。列表的大小取决于先前查询的结果
不要那样做。
这样做:
SELECT <...>
FROM VISIT_VIEW
INNER JOIN (
<previous query goes here>
) t on VISIT_VIEW.VISIT_ID = t.<ID?>
LEFT JOIN INSURANCE ON VISIT_VIEW.visit_id=INSURANCE._fk_visit
答案 1 :(得分:0)
使用以下内容查看是否有任何改进...
IF OBJECT_ID('tempdb..#VisitList', 'U') IS NOT NULL
DROP TABLE #VisitList;
CREATE TABLE #VisitList (
VISIT_ID INT NOT NULL PRIMARY KEY
);
INSERT #VisitList (VISIT_ID) VALUES (1002),(1003),(1005),(1006),(1007),(1008),(1010),(1011),(<...>),(1193),(1194),(1195),(1196),(1197),(1198),(1199);
SELECT
vv.VISIT_ID,
vv.PATIENT_ID,
vv.MRN_ID,
vv.BILL_NO,
ix.INS_PAYOR
FROM
VISIT_VIEW vv
JOIN #VisitList vl
ON vv.VISIT_ID = vl.VISIT_ID
CROSS APPLY (
SELECT TOP 1
i.INS_PAYOR
FROM
INSURANCE i
WHERE
vv.visit_id=i._fk_visit
) ix;