sql-server - 在这种情况下,如何避免使用不同的 TSQL 选择?
问题描述
我正在调整一个在数百万条记录上运行 select distinct 的查询。我对执行计划有点缺乏经验,但我对不同的理解是,我们希望避免使用它,因为清除重复记录需要额外的开销。
有没有办法在不使用 distinct 的情况下重写下面的示例?
IF OBJECT_ID('TEMPDB..#ORDERS', 'U') IS NOT NULL
DROP TABLE #ORDERS
IF OBJECT_ID('TEMPDB..#CUSTOMERS', 'U') IS NOT NULL
DROP TABLE #CUSTOMERS
CREATE TABLE #ORDERS (OrderLineItemID INT IDENTITY(1, 1), OrderID INT, PRIMARY KEY (OrderLineItemID));
CREATE TABLE #CUSTOMERS (CustomerID INT, OrderLineItemID INT, PRIMARY KEY (OrderLineItemID));
INSERT INTO #ORDERS (OrderID)
VALUES (1), (1), (1), (2), (2), (2), (2), (3), (3), (3), (3), (3), (3), (3), (5), (5), (5), (5), (5), (5);
INSERT INTO #CUSTOMERS (OrderLineItemID, CustomerID)
SELECT OrderLineItemID, CASE
WHEN OrderLineItemID <= 3
THEN 15
ELSE 20
END
FROM #ORDERS
查询结果需要拉取CustomerID和OrderID,但是每个订单里面都有一个单独的line item。下面提取所有结果。
SELECT C.CustomerID, O.OrderID
FROM #CUSTOMERS C
JOIN #ORDERS O ON C.OrderLineItemID = O.OrderLineItemID
非明显结果:
CustomerID OrderID
15 1
15 1
15 1
20 2
20 2
20 2
20 2
20 3
20 3
20 3
20 3
20 3
20 3
20 3
20 5
20 5
20 5
20 5
20 5
20 5
但是如果我们在选择中添加 distinct,我们会得到想要的结果。
SELECT DISTINCT C.CustomerID, O.OrderID
FROM #CUSTOMERS C
JOIN #ORDERS O ON C.OrderLineItemID = O.OrderLineItemID
不同的结果:
CustomerID OrderID
15 1
20 2
20 3
20 5
有没有更好的方法来编写它以更有效地执行?
解决方案
您可以使用窗口函数ROW_NUMBER()
来实现相同的结果。不确定,它是否会提供更好的性能。如有疑问,最好测试一下。
SELECT CustomerID, OrderID
FROM
(
SELECT C.CustomerID, O.OrderID, ROW_NUMBER() OVER(PARTITION BY C.CustomerID, O.OrderID ORDER BY (SELECT 1)) AS RNK
FROM #CUSTOMERS C
JOIN #ORDERS O ON C.OrderLineItemID = O.OrderLineItemID) as t
WHERE rnk = 1
推荐阅读
- python - python列表中的重复条目
- html - 在 django 模板中改变云图像
- android - Capacitor v3 一些错误
- hybris - 我如何在 Backoffice config.xml 动态中只读属性
- html - CSS - 对象不在一行中
- javascript - 如何滚动超出 React 中的焦点元素
- python - 如果使用变量值等于 1
- java - 消费者属性 spring cloud 和 kafka binder
- pine-script - Pine 脚本 - 在“show_last”内乘法时出现问题
- java - 带有 aws lambda 处理程序的黄瓜测试配置