我有两张表格如下:
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'
答案 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