2016-11-29 64 views
3

的问题是,这个查询挂起或具有我不知道如何使用的MS Access修复无限记录:SELECT INTO查询使用NOT IN子查询需要较长的时间/挂起

预期的用户输入:

User input Start Date: 1/15/2015 
User input End Date: 11/15/2015 
User input Upper Data Threshold in kB: 50 

源表:

[Master] Table in Access: 
Invc Date Mobile Nbr  PktDtVol 
--------- ----------  -------- 
1/15/15 647-409-8206 48kB 
2/15/15 647-409-8206 33kB 
3/15/15 647-409-8206 8000kB 
4/15/15 647-409-8206 20kB 
5/15/15 647-409-8206 10kB 
6/15/15 647-409-8206 0kB 
7/15/15 718-500-2311 3kB 
8/15/15 718-500-2311 45kB 
9/15/15 718-500-2311 25kB 
10/15/15 514-300-3311 33kB 
11/15/15 514-300-3311 20kB 

输出在[Temp_Table]:

Invc Date Mobile Nbr  PktDtVol Difference in Days 
--------- ----------  -------- ------------------- 
7/15/15 718-500-2311 3kB    304 
8/15/15 718-500-2311 45kB   304 
9/15/15 718-500-2311 25kB   304 
10/15/15 514-300-3311 33kB   304 
11/15/15 514-300-3311 20kB   304 

接受SQL方案产生上述输出:

PARAMETERS [Start Date] DateTime, [End Date] DateTime, [Upper Bound Usage in KB] IEEEDouble; 
SELECT m.[Invc Date], m.PktDtVol, m.[Mobile Nbr], DateDiff("d",[Start Date],[End Date]) AS [Difference in days] 
INTO Temp_Table FROM Master AS m 
WHERE (m.[Invc Date]>=[Start Date] And m.[Invc Date])<=[End Date] AND m.[Mobile Nbr] NOT IN 
(SELECT q.[Mobile Nbr] FROM Master AS q WHERE (q.PktDtVol>=[Upper Bound Usage in KB])); 

从这里,我试图创建一个索引通过另一SQL语句修改表以优化查询,但不工作:

CREATE INDEX Index2 ON Master([Ttl Charges]) 

该查询正常工作,没有挂在源表中的10条记录与多个记录与预期的输出。但是,如果源表中有多条记录的56,000条记录,则会出现此问题。

+1

@ChristopherD。 - 不,那不是他们想要的。有关详细信息,请参阅他们的[早期问题](http://stackoverflow.com/q/40856980/2144390)。 –

+0

大于或等于上限?这看起来是正确的。我建议小于或等于上限。如果它是上面的,你就小于。 – Fionnuala

+0

@Fionnuala'q.PktDtVol> = [上限KB用法]'正常工作。它成功排除了上限用法以上的记录。 – stitch70

回答

3

[Ttl Charges]上的索引不会帮助你,但[PktDtVol]上的索引将会。我只是做了10000行的测试和缺乏[PktDtVol]指数的绝对性能瓶颈:

Indexes: 
    none 
Time: 
    170 seconds (just under 3 minutes) 

Indexes: 
    [Invc Date] 
    [Mobile Number] 
Time: 
    (same as before) 

Indexes: 
    [Invc Date] 
    [Mobile Number] 
    [PktDtVol] 
Time: 
    36 seconds 

支付额外的性能提升,你可以重新制定查询使用LEFT JOIN的,而不是NOT IN子句中带有子查询,如您在评论中提到的:

PARAMETERS [Start Date] DateTime, [End Date] DateTime, [Upper Bound Usage in KB] IEEEDouble; 
SELECT 
    [Master].[Invc Date], 
    [Master].PktDtVol, 
    [Master].[Mobile Nbr], 
    DateDiff("d",[Start Date],[End Date]) AS [Difference in days] 
INTO Temp_Table 
FROM 
    [Master] 
    LEFT OUTER JOIN 
    (
     SELECT DISTINCT q.[Mobile Nbr] FROM Master AS q 
     WHERE (q.PktDtVol>=[Upper Bound Usage in KB]) 
    ) s 
     ON [Master].[Mobile Nbr] = s.[Mobile Nbr] 
WHERE 
    [Master].[Invc Date] >= [Start Date] 
     AND [Master].[Invc Date] <= [End Date] 
     AND s.[Mobile Nbr] IS NULL; 
+0

我很抱歉,我实际上是想将[PktDtVol]放在CREATE INDEX的原始文章中。你是对的,在[Ttl Charges]上创建索引是没有意义的。因此,为我的查询创建索引仍然没有什么区别。这是使用的实际CREATE INDEX:'CREATE INDEX Index2 ON Master([PktDtVol])' – stitch70

+0

在表上创建索引后还有什么需要完成的吗? – stitch70

+0

看来下面可能通过另一个线程在这里工作:[链接](http://stackoverflow.com/questions/40856980/exclusion-condition-for-sql-ms-access-query)。当前成功的查询在以下注释中: – stitch70