【问题标题】:How to improve this SQL?如何改进这个 SQL?
【发布时间】:2015-07-01 00:59:30
【问题描述】:

我的老板给我们发了一个查询,要求我们用更高效的版本替换它并实现以下目标:

PACKAGE 表中获取所有在PASS_PACKAGE_DETAILS 表中至少有1 条记录的记录。

给定 SQL:

SELECT DISTINCT 
    pckg.*  
FROM 
    PASS_PACKAGE pckg 
JOIN 
    PASS_PACKAGE_DETAILS pckg_dtl ON (pckg.PACKAGE_ID = pckg_dtl.PACKAGE_ID) 
WHERE 
    IS_ACTIVE = 1 
    AND '2015/04/22' BETWEEN DATE_START AND DATE_END 
ORDER BY 
    PACKAGE_NAME

如果我错了,请纠正我,但我相信上面的查询会因为JOIN 方法而降低性能。看完this,我想知道我的哪个查询确实达到了我老板的要求,为什么。

我的 SQL:

尝试 #1 - 使用 IN:

SELECT
    pckg.*
FROM 
    PASS_PACKAGE pckg
WHERE 
    IS_ACTIVE = 1
    AND '2015/04/22' BETWEEN DATE_START AND DATE_END 
    AND pckg.PACKAGE_ID IN (SELECT DISTINCT pckg_dtl.PACKAGE_ID 
                            FROM PASS_PACKAGE_DETAILS pckg_dtl)
ORDER BY 
    PACKAGE_NAME

尝试 #2 - 使用 EXISTS:

SELECT 
    pckg.*
FROM 
    PASS_PACKAGE pckg
WHERE 
    IS_ACTIVE = 1
    AND '2015/04/22' BETWEEN DATE_START AND DATE_END 
    AND EXISTS (SELECT pckg_dtl.PACKAGE_ID 
                FROM PASS_PACKAGE_DETAILS pckg_dtl
                WHERE pckg_dtl.package_id = pckg.package_id)
ORDER BY 
    PACKAGE_NAME

希望从这里的专家那里得到一些有价值的信息!

编辑:我正在使用 SQL Server Management Studio。我的执行时间有点奇怪。对于IN 方法,第一次执行大约需要 90+ 毫秒,第二次执行大约需要 200 毫秒,第三次执行需要 90+ 毫秒。所以我不确定我应该参考哪个执行时间。 EXISTS 方法也是如此。

【问题讨论】:

  • 您是否查看过 3 个查询变体的查询执行计划?
  • 比较执行计划,用与实际集合类似的数据进行测试。当可以测量时,无需假设哪个是最好的。
  • 我正在使用 SQL 管理工作室。我的执行时间有点奇怪。对于使用 IN 方法,第一次执行大约需要 90 多毫秒,第二次执行大约需要 200 毫秒,第三次执行回到 90 多毫秒。所以我不确定我应该参考哪个执行时间。
  • 都不行,看方案。
  • 您的架构定义在哪里?您的表和索引统计信息?你的解释计划?也许你应该聘请专业人士。

标签: sql sql-server performance join exists


【解决方案1】:

existsin 是等价的,它们充其量都被优化为一个连接,最坏的情况是......好吧,不是。

您花了几分钟时间输入整个帖子,我建议您查看执行计划,以便更好地利用您的时间。您对“我相信”失去了所有可信度(甚至在阅读其余内容并发现您错了之前),而不是展示硬数据来支持每种选择。

编辑:注意这些查询是不等价的。最上面的一个做了额外的(无用的)排序和过滤(distinct),而其他两个没有。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-11
    • 1970-01-01
    • 1970-01-01
    • 2013-07-21
    • 2015-11-01
    相关资源
    最近更新 更多