【问题标题】:Remove inner query in SQL删除 SQL 中的内部查询
【发布时间】:2018-02-28 05:47:20
【问题描述】:

我们有一个未按照 sql 指南编写的 SQL 查询。我们必须更改查询,但如果我们更改逻辑并删除内部查询,则执行需要很长时间。以下是查询:

 select col1,
         col2,
         case
             when col1 <> '' then(select top 1
                                   col1
                                   from table1 as BP
                                   where bp.col1 = FD.col1 order by BP.col1)
             when col2 <> '' then(select top 1
                                     BP.col2
                                    from table1 as BP
                                    where BP.col2 = FD.col2 order by BP.col2)
             else ''
         end
  from table2 FD

上述查询用于将数据插入临时表。表 1 有近 1 亿条数据。有什么方法可以删除内联查询以及良好的性能。我们已经在 table1 上创建了索引。有什么想法吗?

【问题讨论】:

  • 为什么需要删除内联sql?
  • Table1 有 1 亿条数据,但是 Table2 呢?
  • 我不明白为什么你需要子查询,因为它从外部表table2返回col1 and col2
  • 您应该在此处向我们展示示例数据。子查询并不完全有意义,因为您任意保留了一条记录。
  • 是的。表 1 有数以百万计的数据以及类型。我们正在从 table1 中获取类型。

标签: sql sql-server sqlperformance


【解决方案1】:

试试这个

;WITH CTE
AS
(
SELECT
    RN = ROW_NUMBER() OVER(ORDER BY COALESCE(T2.col1,T2.col2)),
    T2.col1,
    T2.col2,
    T1Val = COALESCE(T2.col1,T2.col2,'')
    FROM table2 T2
       LEFT JOIN table1 T1
          ON
          (
             (
                ISNULL(T2.col1,'')<>'' AND T1.col1 = T2.col1
             )
             OR
             (
                ISNULL(T2.col2,'')<>'' AND T1.col2 = T2.col2
             )
          )
)
SELECT
    *
    FROM CTE
       WHERE RN = 1

【讨论】:

  • CTE会1亿条记录,我认为性能会受到重创。
  • 但它比在内部查询中排名前 1 更好
【解决方案2】:

这是我的微薄帮助:

  1. 您已经可以准备和实现您的子查询 1 和子查询 2(按 col1 或 col2 分组)
  2. 拆分主查询(从 table2 到 3 个不同的查询)
    • 1 与SELECT .. FROM table2 WHERE col1 &lt;&gt; ''
    • 1 与SELECT .. FROM table2 WHERE col1 = '' AND col2 &lt;&gt; ''
    • 1 与SELECT .. FROM table2 WHERE col1 = '' AND col2 = '' 使用INNER JOIN 与您在第一点创建的表。 (如果您使用 SSIS,您可以 // 并将您的内部连接表用于查找)
  3. 如果您的 col1 或 col2 使用 NVARCHAR(MAX) 或大尺寸,您应该查看 HashFunction(例如 MD5)并比较 Hash。
  4. 确保拥有所有索引

至少如果它不是高性能的,您可以尝试: OUTER APPLY (SELECT TOP 1 .. )

另一个想法应该是:

SELECT col1, col2, col1 AS yourNewCol 
  FROM table2 T2
 WHERE EXISTS( SELECT 1 FROM table1 T1 WHERE T1.col1 = T2.col1)

UNION ALL

SELECT col1, col2, col2 AS yourNewCol 
  FROM table2 T2
 WHERE 
      NOT EXISTS( SELECT 1 FROM table1 T1 WHERE T1.col1 = T2.col1)
  AND EXISTS( SELECT 1 FROM table1 T1 WHERE T1.col2 = T2.col2)

UNION ALL

...

我没有给你一个干净的解决方案,但有一些想法。 如果对您有帮助,请告诉我。

问候, 阿诺

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多