优化SQL查询选择案例选择

时间:2019-01-11 20:25:36

标签: sql-server

我在这里寻找一些提到查询优化的线程,但是我无法解决问题。

我需要在SQL Server中执行一个查询,该查询涉及在主选择上使用选择用例,这是对主表的描述:

WS:

| Oid | model_code | product_code | year |

在我的查询中,如果根据某些标准,我的主表中的值存在于另一个表中,那么我需要选择所有这些列以及一个与另一个表进行比较的额外列,让我解释我的另一个表,然后再解释我的意思是这个。

TA:

| Oid | model_code | product_code | year |

两个表都有匹配的列,例如,如果在我的表WS上,我得到以下结果:

| Oid | model_code | product_code | year |
|  1  |      13    |     123      | 2018 |

在我的TA桌上,我有这个:

| Oid | model_code | product_code | year |
|  1  |      25    |     134      | 2016 |
|  2  |      13    |     123      | 2018 |
|  3  |      67    |     582      | 2017 |

我需要在该行上打印“现有”结果,因为主表上的行与此3列值完全匹配。

因此我在该行上的查询应打印如下内容:

| model_code | product_code | year | Exist |
|      13    |     123      | 2018 |  Yes  |

我试图用来实现此目的的查询是这样的:

SELECT 
    WS.Oid, WS.model_code, WS.product_code, Ws.year,
    (SELECT   
         CASE   
            WHEN EXISTS (SELECT 1 FROM TA 
                         WHERE TA.model_code = Ws.model_code 
                           AND TA.product_code = Ws.product_code 
                           AND TA.[Year] = Ws.[Year]) 
               THEN 'Yes'   
               ELSE 'No'   
         END) as 'Exist'
FROM 
    Ws

并且有效,问题在于我的真实表上有更多的列和更多的行(约960,000),例如,一个查询约50,000个元素(使用此查询)需要一分钟多的时间,而同一查询具有相同元素但没有选择大小写的情况,大约需要2秒钟,因此差异为巨大

我确信可以在更短的时间内找到实现这一目标的更可行的方法,但是我不知道如何做到。有什么建议吗?

2 个答案:

答案 0 :(得分:0)

您要做的是将两个表连接在一起,而不是为每个记录寻找匹配的记录。尝试这样的事情:

SELECT 
    WS.model_code, WS.product_code, Ws.year,
        SELECT CASE
            WHEN TA.OID IS NOT NULL THEN 'Yes'
            ELSE 'No'
        END As 'Exist'
FROM WS LEFT OUTER JOIN TA ON
    TA.model_code = Ws.model_code 
         AND TA.product_code = Ws.product_code 
         AND TA.[Year] = Ws.[Year]

这将打印WS表中的所有记录,如果TA表中有匹配的记录,则“存在”列将显示“是”,否则将显示“否”。

这使用一个查询来完成所有操作。您原来的方法是执行一个完全独立的子查询来检查TA表,这会造成性能问题。

您可能还想查看在每个表的这3个字段上放置索引,以使匹配更快。

答案 1 :(得分:0)

除非在那里,否则ta (model_code, product_code, year)上的索引可能会有所帮助。

CREATE INDEX ta_model_code_product_code_year
             ON ta (model_code,
                    product_code,
                    year);

尽管优化器很可能已经以这种方式重写了查询,但是您可以尝试的另一种方法是(显式)使用左联接重写查询。我假设{{1}中的oidNOT NULL

ta

为此,您希望从上方开始索引,也可以尝试一个SELECT ws.oid, ws.model_code, ws.product_code, ws.year, CASE WHEN ta.oid IS NULL THEN 'No' ELSE 'Yes' END exist FROM ws LEFT JOIN ta ON ta.model_code = ws.model_code AND ta.product_code = ws.product_code AND ta.year = ws.year;

ws (model_code, product_code, year)

您可能还想使用索引中列的顺序。如果对于CREATE INDEX ws_model_code_product_code_year ON ws (model_code, product_code, year); 中存在更多唯一值的列,请将其放在ta中存在更少唯一值的列之前。但是,请保持两个索引的顺序相同,即,如果在ta的索引中移动一列,也要以相同的方式在ta的索引中移动它。