【问题标题】:Can I speed up this query by using EXISTS instead of a JOIN?我可以通过使用 EXISTS 而不是 JOIN 来加速这个查询吗?
【发布时间】:2015-10-29 20:55:27
【问题描述】:

我有以下查询,它在一个有超过 2400 万行的数据库上运行,因此它花费的时间太长并且超时。

我希望重写它以使用 EXISTS 来尝试节省性能。

这可能吗?

    SELECT DISTINCT e.EmployeeKey,
                e.EmployeeId,
                dd.Name,
                ed.Text,
                ed.Value,
                ed.ValidFrom,
                ed.ValidTo
FROM EmployeeData ed
INNER JOIN DataDefinition dd ON ed.DataDefinitionId=dd.DataDefinitionId
INNER JOIN Employee e ON ed.EmployeeId=e.EmployeeId
WHERE 1 = 1
  AND (ed.ValidTo > CONVERT(date,GETDATE())
       OR ed.ValidTo IS NULL)
  --AND e.EmployeeKey IN ('NBK8GLU')
  --AND e.EmployeeId IN ('')
ORDER BY 2

【问题讨论】:

  • 不重写查询,让我们看看为什么您的查询可能会这么慢。您可以编辑您的问题以向我们展示您的表格布局和索引定义吗?一些适当的索引可能会解决问题。
  • 遗憾的是,我无法访问它,因为它不是我的数据库,此时我的任务是从中提取一些数据...
  • 如果问题是表没有被索引,那么重写查询不会有任何好处。我唯一能看到的另一件事是 ed.ValidTo 可能已编入索引,但 CONVERT(date,GETDATE()) 调用无法使用该索引。索引是 SQL 优化的关键部分,如果不知道索引是什么,您将在黑暗中开枪。

标签: mysql join exists sql-optimization


【解决方案1】:

第一个也是更经典的方法是用联合打破 Or。类似的东西:

SELECT DISTINCT 
    e.EmployeeKey,
    e.EmployeeId,
    dd.Name,
    ed.Text,
    ed.Value,
    ed.ValidFrom,
    ed.ValidTo
FROM 
    EmployeeData ed
    INNER JOIN DataDefinition dd ON ed.DataDefinitionId = dd.DataDefinitionId
    INNER JOIN Employee e ON ed.EmployeeId = e.EmployeeId
WHERE
    (ed.ValidTo > CONVERT(date,GETDATE())    
ORDER BY 2

Union

SELECT DISTINCT 
    e.EmployeeKey,
    e.EmployeeId,
    dd.Name,
    ed.Text,
    ed.Value,
    ed.ValidFrom,
    ed.ValidTo
FROM 
    EmployeeData ed
    INNER JOIN DataDefinition dd ON ed.DataDefinitionId = dd.DataDefinitionId
    INNER JOIN Employee e ON ed.EmployeeId = e.EmployeeId
WHERE
    ( ed.ValidTo IS NULL)
ORDER BY 2

我也想试试:

SELECT DISTINCT 
    e.EmployeeKey,
    e.EmployeeId,
    dd.Name,
    ed.Text,
    ed.Value,
    ed.ValidFrom,
    ed.ValidTo
FROM 
    EmployeeData ed
    INNER JOIN DataDefinition dd ON ed.DataDefinitionId = dd.DataDefinitionId
    INNER JOIN Employee e ON ed.EmployeeId = e.EmployeeId
WHERE
    ( IsNull( ed.ValidTo, DATEADD( day, 1, GetDate() ) ) > CONVERT( date, GETDATE() )    
ORDER BY 2

【讨论】:

    猜你喜欢
    • 2013-08-15
    • 2011-09-05
    • 2014-02-18
    • 2017-09-09
    • 1970-01-01
    • 1970-01-01
    • 2013-06-23
    • 2023-01-28
    • 1970-01-01
    相关资源
    最近更新 更多