1
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 分钟或更短的时间?

4

6 回答 6

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'
于 2008-12-09T20:05:59.380 回答
0

在不知道 DDL 的情况下,很难测试。30-50K 行仍然只需要几秒钟。

尝试切换 where 子句的顺序。你可能应该已经实现了这个

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

在 where 子句中。

于 2008-12-09T20:01:13.790 回答
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#)

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

于 2008-12-09T20:03:57.980 回答
0

通过良好的优化,您可以在几秒钟内搜索数百万条记录。尽管 StingyJack 在不了解 DDL 的情况下是正确的,但任何查询的优化都是困难的。

优化查询时要做的事情是查看执行计划。嵌套循环等很糟糕。还要确保您也被完全索引。你没有提到有问题的表的索引。如果没有索引,30 - 50k 行可能需要一段时间才能进行这么多的连接。

于 2008-12-09T20:06:29.800 回答
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

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

于 2008-12-09T20:07:20.330 回答
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 表中的方式,他的查询或我的查询可能会更快。

于 2008-12-09T20:15:44.757 回答