在 T-SQL 中将临时表连接到多个列的最快执行方法

发布于 2024-10-25 04:02:05 字数 1416 浏览 1 评论 0原文

我需要编写一个 SQL 查询来从另一个包含过滤器值的表中过滤 4 个潜在列的表。

我想做的示例:

-- This table could have anywhere from 1 to 2000 possible rows
DECLARE @WidgetOwners TABLE (OwnerID INT PRIMARY KEY)
INSERT INTO @WidgetOwners VALUES (5)
INSERT INTO @WidgetOwners VALUES (50)
INSERT INTO @WidgetOwners VALUES (111)
INSERT INTO @WidgetOwners VALUES (12345)
INSERT INTO @WidgetOwners VALUES (6)
--etc...

SELECT w.WidgetID
FROM Widgets w
WHERE w.SellerManagerID IN (SELECT o.OwnerID FROM @WidgetOwners)
OR w.SellerID IN (SELECT o.OwnerID FROM @WidgetOwners)
OR w.BuyerManagerID IN (SELECT o.OwnerID FROM @WidgetOwners)
OR w.BuyerID IN (SELECT o.OwnerID FROM @WidgetOwners)

我的印象是上面查询中的 SUB SELECTS 的性能不会很好。有更好的方法吗?这可以通过多次 LEFT JOINING @WidgetOwner 表来完成吗?这里有人有什么建议吗?

请记住,我现在一直使用 SQL 2000,目前无法升级。

编辑 - 示例 2(这是我正在尝试的其他内容)

SELECT w2.WidgetID, w2.* -- etc
FROM (
    SELECT w.WidgetID
    FROM Widgets w
    INNER JOIN @WidgetOwners o ON w.SellerManagerID = o.OwnerID
    UNION
    SELECT w.WidgetID
    FROM Widgets w
    INNER JOIN @WidgetOwners o ON w.SellerID = o.OwnerID
    UNION
    SELECT w.WidgetID
    FROM Widgets w
    INNER JOIN @WidgetOwners o ON w.BuyerManagerID = o.OwnerID
    UNION
    SELECT w.WidgetID
    FROM Widgets w
    INNER JOIN @WidgetOwners o ON w.BuyerID = o.OwnerID
) x
INNER JOIN Widgets w2 ON x.WidgetID = w2.WidgetID

I need to write a SQL query to filter a table on 4 potential columns from another table of the filter values.

Example of what I am trying to do:

-- This table could have anywhere from 1 to 2000 possible rows
DECLARE @WidgetOwners TABLE (OwnerID INT PRIMARY KEY)
INSERT INTO @WidgetOwners VALUES (5)
INSERT INTO @WidgetOwners VALUES (50)
INSERT INTO @WidgetOwners VALUES (111)
INSERT INTO @WidgetOwners VALUES (12345)
INSERT INTO @WidgetOwners VALUES (6)
--etc...

SELECT w.WidgetID
FROM Widgets w
WHERE w.SellerManagerID IN (SELECT o.OwnerID FROM @WidgetOwners)
OR w.SellerID IN (SELECT o.OwnerID FROM @WidgetOwners)
OR w.BuyerManagerID IN (SELECT o.OwnerID FROM @WidgetOwners)
OR w.BuyerID IN (SELECT o.OwnerID FROM @WidgetOwners)

I am under the impression that the SUB SELECTS in the query above will not perform very well. Is there a better way to do this? Could this be done by LEFT JOINING the @WidgetOwner table multiple times? Does anyone have any recommendations here?

Keep in mind that I am stuck with SQL 2000 right now and cannot upgrade at the moment.

EDIT - Example 2 (This is something else I am trying)

SELECT w2.WidgetID, w2.* -- etc
FROM (
    SELECT w.WidgetID
    FROM Widgets w
    INNER JOIN @WidgetOwners o ON w.SellerManagerID = o.OwnerID
    UNION
    SELECT w.WidgetID
    FROM Widgets w
    INNER JOIN @WidgetOwners o ON w.SellerID = o.OwnerID
    UNION
    SELECT w.WidgetID
    FROM Widgets w
    INNER JOIN @WidgetOwners o ON w.BuyerManagerID = o.OwnerID
    UNION
    SELECT w.WidgetID
    FROM Widgets w
    INNER JOIN @WidgetOwners o ON w.BuyerID = o.OwnerID
) x
INNER JOIN Widgets w2 ON x.WidgetID = w2.WidgetID

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

月野兔 2024-11-01 04:02:05

构建高效查询有许多经验法则。但是,我建议,当性能成为问题时,最好尝试不同的方法并在实践中看看哪种方法表现最好。特别是当行数很大时。

There are many rules of thumb in building efficient queries. But, I would suggest, when performance is a concern, it's always best to experiment with different approaches and to see in practice what performs best. Especially when row counts are large.

寄风 2024-11-01 04:02:05

建议您尝试外连接:

SELECT o1.ownerid, o2.ownerid, o3.ownerid, o4.ownserid
    ... 
FROM widgets w
LEFT JOIN o AS o1 ON w.SellerManagerID = o.OwnerID
LEFT JOIN o AS o2 ON w.SellerID = o.OwnerID
LEFT JOIN o AS o3 ON  w.BuyerManagerID = o.OwnerID
LEFT JOIN o AS o4 ON w.BuyerID = o.OwnerID

如果有帮助,(不知道您的要求,)
您可以使用

COALESCE(o1.OwnerID, o2.OwnerID, o3.ownerID, o4.ownerID)

or

CASE WHEN o1.ownerID IS NULL THEN ...

根据我的经验,外连接几乎总是与任何其他选项一样有效,特别是与相关子查询相比。

当你提到“临时表”时我也担心。

Suggest you try outer joins:

SELECT o1.ownerid, o2.ownerid, o3.ownerid, o4.ownserid
    ... 
FROM widgets w
LEFT JOIN o AS o1 ON w.SellerManagerID = o.OwnerID
LEFT JOIN o AS o2 ON w.SellerID = o.OwnerID
LEFT JOIN o AS o3 ON  w.BuyerManagerID = o.OwnerID
LEFT JOIN o AS o4 ON w.BuyerID = o.OwnerID

If helpful, (not knowing your requirement,)
you can use

COALESCE(o1.OwnerID, o2.OwnerID, o3.ownerID, o4.ownerID)

or

CASE WHEN o1.ownerID IS NULL THEN ...

In my experience outer joins are nearly always as efficient as any other option, especially compared to correlated subqueries.

I also worry when you mention "temp table".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文