【问题标题】:Prevent Select query with Exists condition to reevaluate each time防止使用 Exists 条件的 Select 查询每次重新评估
【发布时间】:2018-08-30 18:10:46
【问题描述】:

我们有一个使用 JET 数据库引擎对 Access 数据库运行的 SQL 查询。不幸的是,我们无法创建任何存储过程或迁移到 SQL Server,这将是我的偏好。 [捂脸]。

问题是查询非常慢。处理请求大约需要 2 分钟,我们必须在 4 个不同的表上执行此操作,因此需要 8 分钟的处理时间。当我们独立运行每个 select 语句时,它们将花费 1-2 秒。当我们将它们放在一起并使用 EXISTS 子句时,它会减慢速度。我们有一个包含两个表的数据库,第一个表大约有 3000 行,第二个大约有 5000 行。我们要选择第一个表中的所有行,其中值 (FieldName) 存在于另一个表的字符串中。我们不需要第二个表中的任何字段,只需知道 FieldName 存在于 VBScript 列中的某个位置。我相信按照这种编写方式,它对每一行(3000 * 5000)的整个第二个表执行查询。有没有办法改变这个查询,这样它就不会执行那么多查找?

SELECT A1.* 
FROM 
    (SELECT * 
     FROM tblEncompasstoCB CB
     WHERE ((NOT CB.VBScript IS NULL) AND (CB.VBScript <> ''))) AS A1
WHERE 
    EXISTS (SELECT * FROM tblMapping
            WHERE (tblMapping.VBScript <> '')
              AND (InStr(tblMapping.VBScript, IIF(INSTR(A1.FieldName, '~') > 0, MID(A1.FieldName, 1, INSTR(A1.FieldName, '~') - 1), A1.FieldName)) > 0))
    OR
    EXISTS (SELECT * FROM tblCustomMapping
            WHERE (tblCustomMapping.VBScript <> '')
              AND (InStr(tblCustomMapping.VBScript, IIF(INSTR(A1.FieldName, '~') > 0, MID(A1.FieldName, 1, INSTR(A1.FieldName, '~') - 1), A1.FieldName)) > 0))

【问题讨论】:

  • 如果你不能改变你的底层架构并且你的记录没有增长并且仍然最大 5000,你可以使用 Linq 将数据加载到内存和查询主题。
  • 您可能可以使用交叉连接来执行此操作,但每当您在查询中看到 InStr 时,它几乎肯定是糟糕的设计。
  • 这对于性能提升来说是非常无望的,因为表之间的键不匹配。
  • 我认为一个小收获是移动 IIF(INSTR(A1.FieldName, '~') > 0, MID(A1.FieldName, 1, INSTR(A1.FieldName, '~') - 1 ), A1.FieldName) 作为初始选择中的字段并为其命名。 (优化 101 - 将事物移至外部“循环”)我的 2c
  • 您能否更具体地说明需要 1-2 秒的时间?我们看不到你所看到的。发布查询!

标签: c# sql database ms-access jet


【解决方案1】:

仅使用 SELECT TOP 1 in exists

【讨论】:

  • 对于任何合理的数据库,只要找到匹配的行,EXISTS 子查询就会停止执行,因此不需要这样做。 (OTOH,OP 正在使用 Access...)
  • 是的,我们使用 EXISTS 是希望它在找到第一个结果时停止执行。
猜你喜欢
  • 2014-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多