需要在SQL Server中加快此查询

时间:2008-12-09 19:54:28

标签: sql sql-server performance tsql outer-join

SELECT pe.prodtree_element_id prodID, pe.prodtree_element_name_s, li.line_name, av2.value
    FROM prodtree_element pe
    LEFT JOIN prodtree_link pl
        ON pe.prodtree_element_id = pl.to_prodtree_node_id
    LEFT JOIN line li
        ON pe.line_code = li.line_code
    INNER JOIN attribute_values av
        ON av.attribute_definition_id = #statusCode# 
    LEFT JOIN attribute_values av2
        ON pe.prodtree_element_id = av.prodtree_element_id
    WHERE pe.prodtree_element_func_type <> 'WIZARD'
        AND pe.prodtree_element_topo_type = 'NODE'

“#statusCode#”是一个静态id,它匹配属性定义表中的id(为了参数,我们假设为22)。问题是,查询在任何合理的时间内完成都会遇到很大麻烦。更大的问题是,我有点需要它提前完成,但记录的数量是巨大的,它必须退缩(约30-50,000)。我需要来自多个表的数据,这是它开始变慢的地方。这只是我需要的一部分,我还需要一个与当前“prodtree_elment_id”相匹配的完整其他表格。

我正在使用ColdFusion,但即使在SQL Server 2005中直接运行查询,也会为此查询创建15-30分钟的等待时间(如果它甚至完成)。是否有任何可以想象的方法来加快查询速度,最多花费5分钟或更短时间?

6 个答案:

答案 0 :(得分:9)

INNER JOIN attribute_values av
    ON av.attribute_definition_id = #statusCode# 
LEFT JOIN attribute_values av2
    ON pe.prodtree_element_id = av.prodtree_element_id

这就是问题所在。 pe和av之间存在交叉连接,然后是交叉连接上的外连接。 你很幸运它只需要30分钟: - )

我想你想要这个:

SELECT pe.prodtree_element_id prodID, pe.prodtree_element_name_s, li.line_name, av2.value
FROM prodtree_element pe
LEFT JOIN prodtree_link pl
    ON pe.prodtree_element_id = pl.to_prodtree_node_id
LEFT JOIN line li
    ON pe.line_code = li.line_code
--replacement
LEFT JOIN
attribute_values av 
         ON pe.prodtree_element_id = av.prodtree_element_id AND
         av.attribute_definition_id = #statusCode# 
--end replacement
WHERE pe.prodtree_element_func_type <> 'WIZARD'
    AND pe.prodtree_element_topo_type = 'NODE'

答案 1 :(得分:0)

不知道DDL很难测试。 30-50K行仍然只需几秒钟。

尝试切换where子句排序。 你可能应该实现这个

 INNER JOIN attribute_values av
        ON av.attribute_definition_id = #statusCode# 

在where子句中。

答案 2 :(得分:0)

我建议的第一件事是你通过企业管理器中的sql优化器实用程序运行它,只要你安装了它。它通常会建议索引和类似的东西,它们可能对查询速度产生积极影响。

要考虑的其他事项是拆分查询。从最初的一瞥看起来,您正在阅读所有具有与您给出的值相匹配的特定属性的产品元素(或类似的东西)。我建议也许:

select * from [bigLongjoin to producttree_element]
where prodtree_element_id
in(
select prodtree_element_id from 
  attribute_values where attribute_definition_id = #statusCode#)

在显示查询计划的企业管理器中运行它也可能会显示瓶颈的位置

答案 3 :(得分:0)

您可以在几秒钟内搜索数百万条记录并进行优化。虽然StingyJack在不知道DDL的情况下是正确的,但任何查询的优化都很困难。

虽然在优化查询时要做的事情是查看执行计划。嵌套循环等很糟糕。还要确保您已完全编入索引。你没有提到有问题的表的索引。没有索引30 - 50k行可能需要一段时间与许多连接。

答案 4 :(得分:0)

如果您可以映射以下内容,请确保您的所有ID都是索引:

pe.prodtree_element_func_type <> 'WIZARD'
        AND pe.prodtree_element_topo_type = 'NODE'

就像是

pe.prodtree_element_func_type_ID <> 1
            AND pe.prodtree_element_topo_type_ID = 2

为了减少需要更多时间才能完成的字符串比较

答案 5 :(得分:0)

SELECT pe.prodtree_element_id prodID, pe.prodtree_element_name_s, li.line_name, av2.value
    FROM prodtree_element pe
    LEFT JOIN prodtree_link pl
        ON (pe.prodtree_element_id = pl.to_prodtree_node_id)
    LEFT JOIN line li
        ON (pe.line_code = li.line_code)
    LEFT JOIN attribute_values av2
        ON (pe.prodtree_element_id IN (SELECT av.prodtree_element_id FROM attribute_values av WHERE av.attribute_definition_id = #statusCode#))
    WHERE pe.prodtree_element_func_type <> 'WIZARD'
        AND pe.prodtree_element_topo_type = 'NODE'
我认为gbn坚持了下来。 即使您将INNER JOIN限制为attribute_values到特定值,它仍然不会与您的主表或其关系完全连接。因此,即使您从查询中获得结果,我的猜测也是有太多。

根据您的意图以及您的数据在attribute_values表中的方式,他的查询或我的查询可能会更快。