【问题标题】:Simple query hangs forever on large table简单查询永远挂在大表上
【发布时间】:2017-02-16 22:01:44
【问题描述】:

我正在尝试使用业务对象前端从另一个开发人员的代码中交叉处理一些代码值(我知道,它不是最理想的,但他们没有给我后端访问权限)。

我需要做的只是从相关表中提取一条记录来比较代码值以显示值。我猜这个问题与包含数百万条记录的表有关。即使我将查询范围缩小到一个值,仅尝试从今天开始的记录,并将检索到的最大行数设置为 1,它也会永远挂起。

它为我的查询生成的代码是:

SELECT
  CLINICAL_EVENT.EVENT_CD,
  CV_EVENT.DISPLAY
FROM
  CLINICAL_EVENT,
  CODE_VALUE  CV_EVENT
WHERE
  ( CLINICAL_EVENT.EVENT_CD=CV_EVENT.CODE_VALUE  )
  AND  
  (
   CLINICAL_EVENT.EVENT_CD  =  338743225
   AND
   CLINICAL_EVENT.EVENT_END_DT_TM
  >  '16-02-2017 00:00:00'
  )

【问题讨论】:

  • 您在运行该查询时是否有任何表锁定?
  • 代码值和相应的显示值实际上都来自表CODE_VALUE。您从连接中获得的唯一好处是根据代码值出现在满足日期标准的CLINICAL_EVENT 行上的次数来复制这些结果。为什么不直接从CODE_VALUE 中选择想要的记录,并从查询中完全消除表CLINICAL_EVENT
  • 联接本身也可能会减少数据。因此,也许一个表中的记录而不是另一个表中的记录需要从结果中排除;因此加入的原因就在那里。 (虽然可以处理虽然存在可能更快)
  • 在 BO 世界中,这两个对象实际上是物理表还是派生表具有自己的开销?
  • @JohnBollinger 按照您的建议删除 CLINICAL_EVENT 表就可以了。如果您想将其添加为答案,我会将其设为已接受的答案:-)

标签: sql business-objects


【解决方案1】:

您能否通过使用连接语法而不是 , 表示法来避免查询中的交叉连接?也许引擎正在优化以避免交叉连接,也许不是。

SELECT
  CLINICAL_EVENT.EVENT_CD,
  CV_EVENT.DISPLAY
FROM
  CLINICAL_EVENT
INNER JOIN CODE_VALUE  CV_EVENT
 on  CLINICAL_EVENT.EVENT_CD=CV_EVENT.CODE_VALUE
WHERE CLINICAL_EVENT.EVENT_CD  =  338743225 
  AND CLINICAL_EVENT.EVENT_END_DT_TM  >  '16-02-2017 00:00:00'

另外,什么数据类型是 EVENT_END_DT_TM 可能隐式地将您的 '16-02-2017 00:00:00' 转换为日期或日期时间会有助于提高性能。

【讨论】:

  • 如果数据库不以与您建议的替代方式完全相同的方式处理 OP 的查询,那将是令人惊讶的。无论如何,不​​要忽视 OP 不能直接访问 DB。他提出的查询是软件生成的,他似乎不太可能充分控制发送到数据库的内容以实施您的建议。
  • 在BO中,您可以随时进入报表的SQL视图,取消选中自动生成SQL并修改SQL(前提是您有权限这样做)
【解决方案2】:

扩展一下我的评论:

您要检查的代码值和相应的显示值实际上都来自表CODE_VALUE。您从联接中获得的唯一好处是根据代码值出现在满足日期标准的CLINICAL_EVENT 行上的次数重复这些结果(在某种意义上,包括抑制 all如果没有匹配的行,则出现)。

您似乎只想比较代码值和相应的描述,而不是评估该代码出现了多少次。在这种情况下,通过加入CODE_VALUECLINICAL_EVENT,您会招致大量不需要的工作——甚至可能是一些不需要的工作。相反,只需直接从 CODE_VALUE 单独选择所需的行。

【讨论】:

    猜你喜欢
    • 2018-01-13
    • 1970-01-01
    • 1970-01-01
    • 2021-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多