SQL Server中联接子查询的效率

SQL Server中联接子查询的效率,sql,sql-server,join,subquery,left-join,Sql,Sql Server,Join,Subquery,Left Join,我在SQLServer2008R2中有一个客户和订单表。两者都有名为id的客户id索引。我需要返回customers表中所有客户的详细信息和orders表中的信息,例如第一个订单的详细信息 目前,我在orders表的子查询中留下了join my customers表,子查询返回我需要的有关订单的信息。例如: SELECT c.id ,c.country ,First_orders.product ,First_orders.order_

我在SQLServer2008R2中有一个客户和订单表。两者都有名为id的客户id索引。我需要返回customers表中所有客户的详细信息和orders表中的信息,例如第一个订单的详细信息

目前,我在orders表的子查询中留下了join my customers表,子查询返回我需要的有关订单的信息。例如:

SELECT c.id
        ,c.country      
        ,First_orders.product
        ,First_orders.order_id
FROM customers c

LEFT JOIN   SELECT( id, 
                    product 
            FROM (SELECT    id
                            ,product
                            ,order_id
                            ,ROW_NUMBER() OVER (PARTITION BY id ORDER BY Order_Date asc) as order_No 
                        FROM orders) orders
            WHERE Order_no = 1) First_Orders
ON c.id = First_orders.id
我对SQL非常陌生,希望了解我是否能有效地执行此操作。最后,我在一个select查询中将许多类似的子查询加入到customers表中,运行起来可能需要几十分钟

那么,我这样做是否有效,或者是否可以改进?例如,我不确定orders表中id上的索引是否有用,也许我可以先创建子查询中的内容的临时表,然后在临时表中创建id上的唯一索引,以便SQL Server知道id现在是唯一列,然后将我的customers表连接到此临时表,从而加快查询速度?我通常在customers和orders表中有一到两百万行


非常感谢

对于刚刚学习SQL的人来说,您的查询看起来相当不错

客户索引可能用于查询,也可能不用于查询-您需要查看执行计划。ordersid、order\u date上的索引可以非常有效地用于row\u number函数


一个评论是关于字段的命名。字段orders.id不应该是客户id。它应该类似于“orders.customer\u id”。在表之间保持命名系统的一致性将有助于您今后的工作。

您可以删除其中一个子查询,以提高效率:

SELECT c.id
        ,c.country      
        ,First_orders.product
        ,First_orders.order_id
FROM customers c
   LEFT JOIN  (SELECT id
                    ,product
                    ,order_id
                    ,ROW_NUMBER() OVER (PARTITION BY id ORDER BY Order_Date asc) as order_No 
               FROM orders) First_Orders
     ON c.id = First_orders.id AND First_Orders.order_No = 1

在上面的查询中,您需要小心放括号的位置,因为我认为这样做行不通。此外,在结果中返回product,但不包括在嵌套子查询中

试试这个……它很容易理解

;WITH cte
AS (
    SELECT id
        ,product
        ,order_id
        ,ROW_NUMBER() OVER (
            PARTITION BY id ORDER BY Order_Date ASC
            ) AS order_No
    FROM orders
    )
SELECT c.id
    ,c.country
    ,c1.Product
    ,c1.order_id
FROM customers c
INNER JOIN cte c1 ON c.id = c1.id
WHERE c1.order_No = 1

从可读性的角度来看,大多数SQL开发人员都会尽量避免这样的嵌套子查询。如果需要像这样链接派生表,则首选通过WITH命令前缀使用CTE。从性能上看,它不应该有任何区别,这只是一个惯例和可读性的问题。