我在这里寻找一些提到查询优化的线程,但是我无法解决问题。
我需要在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秒钟,因此差异为巨大。
我确信可以在更短的时间内找到实现这一目标的更可行的方法,但是我不知道如何做到。有什么建议吗?
答案 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}中的oid
是NOT 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
的索引中移动它。