Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL查询优化,查看前x个记录数_Sql_Sql Server - Fatal编程技术网

SQL查询优化,查看前x个记录数

SQL查询优化,查看前x个记录数,sql,sql-server,Sql,Sql Server,这个查询可以工作,但是有更好的方法来编写这个查询吗?当前的一个似乎很慢。情况非常简单 我有两张桌子,顾客和付款。Customers表包含了您所期望的客户信息。付款表记录客户每月支付的款项。它有几个字段我们需要查看-DueDate、PaymentDate和CustomerID 我想问的问题是,我想问的是,所有在前12次付款中迟到至少3个月的客户。下面是我的问题,但似乎很慢。有没有比下面更好的方法来写这篇文章 SELECT CustomerID FROM Customers AS C WHE

这个查询可以工作,但是有更好的方法来编写这个查询吗?当前的一个似乎很慢。情况非常简单

我有两张桌子,顾客和付款。Customers表包含了您所期望的客户信息。付款表记录客户每月支付的款项。它有几个字段我们需要查看-DueDate、PaymentDate和CustomerID

我想问的问题是,我想问的是,所有在前12次付款中迟到至少3个月的客户。下面是我的问题,但似乎很慢。有没有比下面更好的方法来写这篇文章

SELECT  CustomerID
FROM    Customers AS C
WHERE   EXISTS ( SELECT DueDate, CustomerID, PaymentDate
                 FROM   ( SELECT TOP 12 *
                          FROM      Payments as P
                          WHERE     P.CustomerID = C.CustomerID
                          ORDER BY PaymentDate
                        ) AS First12Payments
                 WHERE  DATEDIFF(MONTH, First12Payments.DueDate, First12Payments.PaymentDate) > 3 )

谢谢

乔·伊诺斯和布兰登评论中的建议很好。但是,如果您不能添加该列,那么对SQL语句进行两个小的更改可能会使它更快一些。为了更好,您可能需要在Payments表的DueDate和PaymentDate列中添加索引

SELECT  CustomerID
FROM    Customers AS C
WHERE   EXISTS ( SELECT 1 -- no need for a columns list since you only check for existance
    FROM (SELECT TOP 12 DueDate, PaymentDate -- no need for all the columns, only the ones you use
          FROM      Payments as P
          WHERE     P.CustomerID = C.CustomerID
          ORDER BY PaymentDate
         ) AS First12Payments
        WHERE  DATEDIFF(MONTH, First12Payments.DueDate, First12Payments.PaymentDate) > 3 

一个简单的优化方法是在付款表中添加一个新的“MonthsLate”列,这是预先计算的。然后,您可以直接在该列上进行筛选,而不是在计算中进行筛选。@JoeEnos,如果您对monthsate列进行索引,它将运行。它甚至可以是一个过滤索引
,其中MonthsLate不为null
,这样从不延迟付款的客户就不会产生维护开销。
选择1
,而不是选择exists中的列,尽管看起来更好,但不会影响性能。SQL Server是智能的,它知道它正在用于一个
存在的
,并且实际上不返回任何数据。看见最小化内部select的列应该会有帮助。@DaveZych谢谢,我不知道。这是我几年前从一位DBA那里得到的一个建议,我想微软从那以后已经改进了SQL Server:-)谢谢@DaveZych和Zohar,我也不知道EXISTS关键字。示例中的1/0非常棒。