Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 非常慢的查询,我有什么选择?_Sql Server_Tsql_Optimization_Database Design_Query Optimization - Fatal编程技术网

Sql server 非常慢的查询,我有什么选择?

Sql server 非常慢的查询,我有什么选择?,sql-server,tsql,optimization,database-design,query-optimization,Sql Server,Tsql,Optimization,Database Design,Query Optimization,我在医院做了一些sql工作(还没有新冠病毒病例!)。有一个表,[dbo].a.diagnosis,其中包含我们所有患者的所有诊断的历史记录。我不是专家,但是桌子是。。。糟糕。这个古老的软件使用它来处理诊断(以及其他事情)。按照表的工作方式,它有30多个列和300k多个行,但没有索引(主键除外)。每次患者更新诊断时,他们的所有诊断都会重新写入新的诊断\u日期下的表中诊断日期存储在数据类型日期中,而不是日期时间,但患者一天内多次更新诊断并不罕见 我需要得到一份目前所有住院患者的名单,并合理地更新(我

我在医院做了一些sql工作(还没有新冠病毒病例!)。有一个表,
[dbo].a.diagnosis
,其中包含我们所有患者的所有诊断的历史记录。我不是专家,但是桌子是。。。糟糕。这个古老的软件使用它来处理诊断(以及其他事情)。按照表的工作方式,它有30多个列和300k多个行,但没有索引(主键除外)。每次患者更新诊断时,他们的所有诊断都会重新写入新的
诊断\u日期下的表中<代码>诊断日期
存储在数据类型
日期
中,而不是
日期时间
,但患者一天内多次更新诊断并不罕见

我需要得到一份目前所有住院患者的名单,并合理地更新(我想说在过去24小时内是合理的,但最好早点)

我当前的最佳查询在运行时仍然是高度可变的,运行时间从1到15(!!!)分钟不等。这是不可接受的,所以我想知道我的选择是什么来改进它

数据示例(虚构,仅相关列):

查询:

SELECT DISTINCT dx.patient_id -- (decimal(10,0), null)
,       dx.diagnosis_date -- (date, null)
,       dx.diagnosis_code -- (varchar(5), null)
,       dx.diagnosis_text -- (varchar(253, null) 
,       dx.diagnosis_type -- (varchar(1), null)
FROM    [dbo].A.patients -- Starting with a list of our current patients.
JOIN    [dbo].A.diagnosis dx
    ON  [dbo].A.patients.patient_id = dx.patient_id
JOIN    [dbo].B.diagnosis_priority dp 
    ON  dx.diagnosis_type = dp.diagnosis_type
-- This is a table I wrote to help determine which diagnoses are more 'up-to-date' if multiple updates are done on 
-- a single day. The join assigns a priority number to each diagnosis_type as diagnosis_priority.
WHERE   dx.diagnosis_code IS NOT NULL
AND     dx.diagnosis_date = ( -- Trying to get the diagnoses as of the most recent diagnosis date.
            SELECT  MAX(dx_a.diagnosis_date) 
            FROM    [dbo].A.diagnosis dx_a 
            WHERE   dx_a.patient_id = dx.patient_id
            ) 
AND     dp.diagnosis_priority = (  
-- Trying to get the highest priority diagnoses applied on the most recent date.
-- A patient will not get a lower priority diagnosis on a later date, but newer diagnoses will not 
-- necessarily get a higher priority in [dbo].A.diagnosis
            SELECT  MAX(dp_a.diagnosis_priority) 
            FROM    [dbo].A.diagnosis dx_a 
            JOIN    [dbo].B.diagnosis_priority dp_a 
                ON dx_a.diagnosis_type = dp_a.diagnosis_type 
            WHERE dx_a.patient_id = dx.patient_id
            )
我是
[dbo].a上
db\u datareader
的成员,但我是同一服务器上
[dbo].B上
db\u owner
的成员。修改方法[dbo].A.诊断功能是不可行的,因为上面提到的是一个古老的软件


如果查询无法显著改进,我想知道我在
[dbo].B上有哪些选项来维护当前住院患者的当前诊断列表。

将所有数据流式输出到临时表,并在临时表上运行查询

CREATE TABLE #diagnosis_tmp (patient_id decimal(10,0), diagnosis_type varchar(1), diagnosis_date date, diagnosis_code varchar(5), diagnosis_text varchar(253))

INSERT INTO #diagnosis_tmp (patient_id,diagnosis_type,diagnosis_date,diagnosis_code)
SELECT patient_id,diagnosis_type,diagnosis_date,diagnosis_code
FROM [dbo].A.diagnosis
    WHERE diagnosis_code IS NOT NULL

--CREATE INDEX i_patient_date ON #diagnosis_tmp (patient_id,diagnosis_date)

您在这里提供的示例数据只是一个表的数据,上面有5个表引用。
DISTINCT
和仅引用
dx
的列,即使在
FROM
中有3个表,在
中的子查询中有另外2个表,其中
具有“代码气味”。但是,发布查询计划(使用粘贴计划)和对象(包括索引)的DDL可能会帮助我们,我怀疑您实际需要的是
存在于
WHERE
中的
,如果您使用CTE和窗口函数,甚至可能不需要该子查询。
数据库“a”中的SHOWPLAN权限被拒绝
,然后我建议与您的一位DBA联系以寻求帮助。如果没有查询计划、DDL和索引,我们将面临一项不可能完成的任务。我们可能会重写查询,但我们仍然会对数据和预期结果进行采样,并对所涉及的逻辑进行描述。一个不可能完成的任务就是我所拥有的。开始的一些技巧-将内部查询移动到CTE,因为现在它们正在为每一行运行。下一步-限制结果集以获得尽可能少的结果-然后您可以提取包含所需数据的临时表并在其上创建索引。如果你能提供更多的信息,这会很有用,
CREATE TABLE #diagnosis_tmp (patient_id decimal(10,0), diagnosis_type varchar(1), diagnosis_date date, diagnosis_code varchar(5), diagnosis_text varchar(253))

INSERT INTO #diagnosis_tmp (patient_id,diagnosis_type,diagnosis_date,diagnosis_code)
SELECT patient_id,diagnosis_type,diagnosis_date,diagnosis_code
FROM [dbo].A.diagnosis
    WHERE diagnosis_code IS NOT NULL

--CREATE INDEX i_patient_date ON #diagnosis_tmp (patient_id,diagnosis_date)