sql - 更高效的SQL查询

标签 sql sql-server

好的,我正在做数据转换。我的新数据库表中有大约 12 列,我只需要在旧数据库中查找每个产品的最新交易。在我的查询中,有十二次我需要来自大量交易表的单个值。

为了获取最新的交易,我使用嵌套的内部联接来查找“最大值”。这些嵌套查询会降低效率,而且子表也很大。当仅提取 100 个产品的样本时,我的查询大约需要 20 秒。我有〜10,000。有什么建议可以使我的嵌套查询更有效吗?下面是这些嵌套内部联接之一的示例。

   LEFT JOIN coverage_schedule CS_PL
     ON R.risk_pk = CS_PL.risk_fk
        AND CS_PL.coverage_type = 'HOMCVGE'
   LEFT JOIN ( Coverage_tran CT_PL
               JOIN (SELECT DISTINCT MAX(pct.coverage_tran_pk) AS recent,
                                     pct.coverage_schedule_fk,
                                     pcs.coverage_type
                     FROM   Coverage_tran pct
                            LEFT JOIN TRANSACTION pt
                              ON pct.transaction_fk = pt.transaction_pk
                            LEFT JOIN coverage_schedule pcs
                              ON pct.coverage_schedule_fk =
                                 pcs.po_coverage_schedule_pk
                                 AND pcs.coverage_type = 'HOMCVGE'
                     WHERE  pt.transaction_cycle = 'issued'
                            AND pct.cvg_status = 'Active'
                     GROUP  BY pct.coverage_schedule_fk,
                               pcs.coverage_type,
                               pt.transaction_cycle) mCT2
                 ON CT_PL.coverage_schedule_fk = mCT2.coverage_schedule_fk
                    AND CT_PL.coverage_tran_pk = mCT2.recent )
     ON CS_PL.coverage_schedule_pk = CT_PL.coverage_schedule_fk
        AND CT_PL.cvg_status = 'Active'  

我尝试将嵌套表查询限制为仅具有正确“覆盖类型”的事务,在此示例中,覆盖范围称为“HOMCVGE”,我还限制为仅具有“事件”状态的产品。我还尝试从表中删除“覆盖”列,因为我不需要它既作为列又作为连接的限制/规则。我认为限制样本大小会提高效率,但我没有看到明显的效果。我是否只需要通过添加更多限制来缩小表大小?将限制放在“join”子句中还是“where”子句中更好?

执行计划显示上面的嵌套查询的成本为 11.6911/8% 这大约是整个查询中最昂贵的事情......但这只是告诉我它减慢了速度,我已经知道了。

我可以使用任何提示、线索或工具吗?我承认我没有上过 SQL 类(class),所以我没有学到任何最佳实践,也不知道 Big O 成本。哎呀,我 10 分钟前才找到执行计划。

更新-------------------- 通过删除不必要的列和分组,我能够节省几秒钟的时间。所以谢谢。我希望我能让它变得更有效率。我还发现,如果可能的话,最好在“where”子句中添加对查询的限制,而不是直接附加到“JOIN”子句。

X-Zero,在我看来我有两个选择。基本上我正在寻找产品的当前功能。在新数据库中,我将当前功能作为单独的列导入。在旧数据库中,功能存储在一个巨大的事务表中,其中包含产品上与添加、删除或仅引用功能更改相关的所有事务。产品上的每个功能在表中都有自己的事务集。如果产品从未有过该功能,则根本不会有任何记录。 (因此使用左连接)我也不会提取表中的每个特征类型,而只是提取 12 个特征类型。所以我可以:

  1. 按照您所说的操作,使用 CTE 制作一个简化的交易表,其中仅包含相关功能集的最新活跃交易,然后在我的主查询中按产品从该表中提取。

  2. 正如我现在所做的那样,每个功能在主查询中都有自己单独的子查询/最近事务表。这些表仅包含一项功能。我尝试使这些子查询相同,但由于表中的许多功能类型我根本没有使用,因此使它们独一无二会更有效。

我不确定哪种方式更好。听起来 CTE 可能是可行的方法(只要我将其限制为我想要的 12 个功能),但这是另一件事要自学。

最佳答案

去掉子查询中的DISTINCT关键字; MAX 只会为每个 GROUPing 列返回一个值,因此 DISTINCT 是多余的。

编辑:下面马丁的评论是正确的,但它确实增加了子查询中出现错误的可能性。您需要按所有三列分组还是仅前两列分组?如果是前者,那么我收回我的回答;如果是后者,您需要清理您的样本:)

关于sql - 更高效的SQL查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7825683/

相关文章:

sql - SQL 代理作业失败时在电子邮件中生成错误完整消息

sql - BigQuery SQL : How to check dual conditions in CASE expression and assign single value?

java - Oracle 查询给出错误 - SQL 命令未正确结束

sql-server - Linux + Django + SQLServer

php - 更新网站与 WordPress 和其他网站使用的类似功能

mysql - 如何使用 MySQL 将多个表合并为一个表?

php - 创建警报并在警报后继续此页面

SQL Server : inserting Player vs Player names in to new table from tblEntrants

sql - 如何在SQL中为每个组选择一个最大行

sql - SQL SERVER查询结果中的单行分隔记录