从表中获取记录的最有效方法,每个月在另一个表中存在记录

时间:2017-02-28 04:32:37

标签: sql tsql sql-server-2012

我有两张表格如下:

User: User_ID, User_name and some other columns (has approx 1000 rows)
Fee: Created_By_User_ID, Created_Date and many other columns (has 17 million records)

费用表没有任何索引(我无法创建索引)。

我需要一年中每个月(比如说2016年)的用户列表,他们至少创建了一个费用记录。

我确实有一个工作查询,需要很长时间才能执行。有人可以用更好的查询来帮助我吗?可能正在使用EXIST子句(我尝试了一个,但在扫描Fee表时仍需要时间)

SELECT MONTH(f.Created_Date), f.Created_By_User_ID
FROM Fees f 
JOIN [User] u ON f.Created_By_User_ID= u.User_ID
WHERE f.Created_Date BETWEEN '2016-01-01' AND '2016-12-31'

3 个答案:

答案 0 :(得分:1)

您需要在正在使用的原始查询中对费用表进行一次全面扫描。如果您直接使用连接,就像在原始查询中一样,您将需要对费用表进行多次扫描,其中许多将在连接发生时通过冗余行。当您使用Mansoor建议的内部查询时,将发生相同的情况。

优化可以是减少连接发生的行数。 假设用户表每个用户只包含一条记录,并且费用表每人有多条记录,我们可以尝试使用CTE查找用户购买的不同月份。 然后我们可以在这个CTE之上进行连接,这将减少连接执行的计算,并且在执行大型数据集时应该提供稍微更好的输出时间。

试试这个:

WITH CTE_UserMonthwiseFeeRecords AS 
(
SELECT DISTINCT Created_By_User_ID, MONTH(Created_Date) AS FeeMonth
FROM Fee
WHERE Created_Date BETWEEN '2016-01-01' AND '2016-12-31'
)
SELECT User_name, FeeMonth
FROM CTE_UserMonthwiseFeeRecords f 
INNER JOIN [User] u ON f.Created_By_User_ID= u.User_ID

此外,您没有提到您需要用户名和所有内容,如果只是为了找到每月进行购买的不同用户而需要id,那么您可以在CTE中使用查询,甚至不需要JOIN as:

SELECT DISTINCT Created_By_User_ID, MONTH(Created_Date) AS FeeMonth
FROM Fee
WHERE Created_Date BETWEEN '2016-01-01' AND '2016-12-31'

答案 1 :(得分:0)

// $scope is such your flexgrid object
$scope.itemFormatter = function(panel, r, c, cell) {
    var cellBinding = panel.columns[c].binding;
    if (panel.cellType == wijmo.grid.CellType.ColumnHeader) {
        cell.style.textAlign = 'center';
    }
}

答案 2 :(得分:0)

您可以尝试使用此方法来减少查询运行时间。然而,它确实复制了巨大的数据并存储了一个表的实例(Temp_Fees),在表上执行的每个DML费用/用户都要求截断并重新加载表Temp_Fees。

Select * into Temp_Fees  from  (SELECT MONTH(f.Created_Date) as Created_MONTH, f.Created_By_User_ID
FROM Fees f 
WHERE f.Created_Date BETWEEN '2016-01-01' AND '2016-12-31' )


SELECT f.Created_MONTH, f.Created_By_User_ID
FROM Temp_Fees  f 
JOIN [User] u ON f.Created_By_User_ID= u.User_ID