【问题标题】:How can I make this SQL query more efficient?如何使这个 SQL 查询更高效?
【发布时间】:2015-05-27 21:49:07
【问题描述】:

我有一个查询试图从多个表中提取数据,但是当我运行它时,它需要很长时间(所以我什至无法等待足够长的时间)。我知道它的效率极低,并希望获得一些关于如何更好地编写它的意见。这里是:

SELECT 
        P.patient_name, 
        LOH.patient_id, 
        LOH.requesting_location, 
        LOH.sample_date,
        LOH.lab_doing_work,
        L.location_name, 
        LOD.test_code, 
        LOD.test_rdx,
        LSR.tube_type 
FROM 
        mis_db.dbo.lab_order_header AS LOH, 
        mis_db.dbo.patient AS P, 
        mis_db.dbo.lab_order_detail AS LOD, 
        mis_db.dbo.lab_sample_rule AS LSR,
        mis_db.dbo.location AS L
WHERE 
        LOH.requesting_location = '000839' AND
        LOH.lab_order_id = LOD.lab_order_id AND
        LOH.sample_date IN ('05/28/2015', '05/29/2015') 
        --LOH.patient_id = LOD.patient_id 
        --LOD.sample_date = LOH.sample_date 
ORDER BY 
        P.patient_name DESC 

【问题讨论】:

  • 和往常一样:在“决策上下文”中使用的任何字段(例如joinwhere 等)都应该有一个索引。
  • 您使用的是哪个 DBMS?后格雷斯?甲骨文?
  • SQL 管理工作室
  • SQL Management Studio 不是 DBMS。它是 SQL Server 的管理工具(一个 DBMS)。您确实应该了解您正在使用的数据库引擎;它使查找有关它的信息和提出问题变得更加容易(并让您更快地得到答案)。我已经为你添加了合适的标签。
  • @usr 。 . .你在回答错误的问题。 OP关心性能。我想如果他更详细地查看结果,他也会担心重复。

标签: sql sql-server performance optimization


【解决方案1】:

试试这个(或类似的)

SELECT P.patient_name, 
    lo.patient_id, lo.requesting_location, 
    lo.sample_date, lo.lab_doing_work,
    l.location_name, d.test_code, d.test_rdx,
    d.tube_type 
FROM mis_db.dbo.lab_order_header lo 
    join mis_db.dbo.patient p on p.patient_id = lo.Patient_id
    join mis_db.dbo.lab_order_detail d on d.lab_order_id = lo.lab_order_id
    join mis_db.dbo.lab_sample_rule r on r.rule_id = lo.ruleId   -- ???? 
    join mis_db.dbo.location  l on l.locationid = lo.requesting_location  
WHERE lo.requesting_location = '000839' AND
     lo.sample_date IN ('05/28/2015', '05/29/2015') 
ORDER BY p.patient_name DESC 

【讨论】:

    【解决方案2】:

    我最终采用了以下方法并能够得到我想要的结果:

    SELECT       LOH.patient_id,
                   patient_name,
                             [mis_db_rpt].[common].[string_date_format](LOD.sample_date) AS
                   [Draw Date],
                   test_description,
                   LOD.test_code,
                   LOH.lab_doing_work,
                   tube_type,
                   L.short_name
    FROM                   [mis_db].[dbo].[lab_order_header] 
                   LOH
          INNER JOIN
                             [mis_db].[dbo].[lab_order_detail] 
                   LOD 
          ON     LOH.lab_order_id = LOD.lab_order_id
          INNER JOIN
                             [mis_db].[dbo].[patient] 
                   P 
          ON     P.patient_id = LOD.patient_id         
          INNER JOIN
                             [mis_db].[dbo].[sample_tube]
                   ST
          ON     LOD.sample_id = ST.sample_id
          INNER JOIN
                             [mis_db].[dbo].[location] AS
                   L
          ON     LOH.lab_doing_work = L.location_id
          INNER JOIN
                             [mis_db].[dbo].[lab_test] AS
                   LT
          ON     LOD.test_code = LT.test_code         
    WHERE       LOH.requesting_location = '000839' AND
    LOD.sample_date IN ('05/28/2015', '05/29/2015') 
    ORDER BY  LOD.sample_date,
                             patient_name,
                             LOD.patient_id,
                             test_description
    

    【讨论】:

      【解决方案3】:

      我会试试的

      1. 单击以在 SSMS 中运行估计的执行计划,看看它是否建议任何缺失的索引。我认为 lo.requesting_location 和 sample_date 上的非聚集索引可能有助于过滤器
      2. 在 p.patient_name 的 desc 索引中也可能有助于提高 order by 的性能。
      3. 尝试将 IN 日期过滤器更改为“介于 '05/28/2015' 和 '05/29/2015' 之间”

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-05-23
        • 1970-01-01
        • 1970-01-01
        • 2016-04-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多