Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.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 我可以改进此查询以用于大型表吗?_Sql_Oracle - Fatal编程技术网

Sql 我可以改进此查询以用于大型表吗?

Sql 我可以改进此查询以用于大型表吗?,sql,oracle,Sql,Oracle,如何改进此查询以便在大型表中使用 我使用“DataValues”表存储集合“Visit_id”的值“Value”集合,即它记录每次访问的特定值 我使用表“MatchItems”来存储值“Value”的动态匹配集“MatchSet”,集合可以包含任意数量的值。该表还有一个IsNeg字段,用于指示匹配是否需要在访问集合中不存在值 这允许我动态匹配符合某些标准的访问,例如 必须包含值A、B和C而不是D或C和B而不是A ie值=A,值=B,值=C,值/=D 或值=C,值=B,值/=A 我有一个可以提供合

如何改进此查询以便在大型表中使用

我使用“DataValues”表存储集合“Visit_id”的值“Value”集合,即它记录每次访问的特定值

我使用表“MatchItems”来存储值“Value”的动态匹配集“MatchSet”,集合可以包含任意数量的值。该表还有一个IsNeg字段,用于指示匹配是否需要在访问集合中不存在值

这允许我动态匹配符合某些标准的访问,例如 必须包含值A、B和C而不是D或C和B而不是A

ie值=A,值=B,值=C,值/=D 或值=C,值=B,值/=A

我有一个可以提供合理解决方案的查询:


如果DataValues表包含100m条记录,MatchItems可能包含50组2-20个值的集合,如何提高此查询的性能?

您可以使用分析函数尝试此版本,看看它的性能是否更好。此查询将删除要加入的子查询GpMatchItems

选择不同的匹配集, 探访, TGT账户, 匹配访问次数, isneg_sum 从选择MatchItems.MatchSet, DataValues.Visit_id, 计数不同大小写MatchItems.IsNeg(0时),然后计算MatchItems.id ELSE NULL结束 通过MatchItems.MatchSet进行分区 作为tgtcount, 按MatchItems.MatchSet、DataValues.Visite\u id划分的分区上的计数* 作为一场比赛, 按MatchItems.MatchSet、DataValues.Visite\u id在分区上求MatchItems.IsNeg之和 作为负和 从DataValues左侧连接MatchItems.VALUE=DataValues.VALUE上的MatchItems 其中tgtcount=match\u visit\u count,isneg\u sum=0;
我已经调整了EJ的建议,包括一个左连接来收集TGT帐户,以确定每个匹配集中所需的良好匹配的总数:

SELECT DISTINCT matchset,
              visit_id,
              tgtcount,
              match_visit_count,
              isneg_sum
              GpMatchItems.count tgtCount 
FROM 
             COUNT (*) OVER (PARTITION BY MatchItems.MatchSet, DataValues.Visit_id)
                 AS match_visit_count,
             SUM (MatchItems.IsNeg) OVER (PARTITION BY MatchItems.MatchSet, DataValues.Visit_id)
                 AS isneg_sum
        FROM DataValues 
        LEFT JOIN MatchItems ON MatchItems.VALUE = DataValues.VALUE)
        LEFT JOIN ( SELECT 
                     MatchItems.MatchSet,
                     count(*) Count
                 FROM MatchItems
                 WHERE MatchItems.IsNeg = 0
                 GROUP BY
                     MatchItems.MatchSet) GpMatchItems 
                 ON GpMatchItems.MatchSet = MatchItems.MatchSet
         )
WHERE 
tgtcount = match_visit_count 
AND isneg_sum = 0;

首先要考虑的是查询读取的行数。您的筛选条件IsNeg=0似乎选择了60%或更多的行;在1亿行表中,查询读取的是6000万行。对于可能需要几个小时才能运行的批处理查询,可以这样做,但对于交互式查询则不行。您的使用案例是什么?感谢EJ,这是一个技巧,它显著提高了性能。嗨EJ-此解决方案存在一个问题,TGT计数匹配集中的所有匹配项,它应该计数匹配集中的所有匹配项,然后我们使用TGT计数检查是否有所有所需的匹配项。如果我将MatchItem.Id中的“Y”编辑为“Z”,它仍然会将Visit_Id返回为有效,即使MICKEY/=MICKEZ。在示例查询中,您只计算isNeg=0的MatchItems,这就是我的解决方案所做的。如果您不关心isNeg值,那么只需删除case语句并使用MatchItems。在示例中,isNeg=0确保不包含任何负匹配,并且找到的匹配总和必须与匹配集中所需的匹配总和相同,这就是为什么我加入了到GpMatchItems的联接来计算每个匹配集中所需的所有匹配项。TGT计数仅计算DataValues表中某个位置具有匹配项的匹配项记录,因为左侧联接位于MatchItems.VALUE=DataValues.VALUE上。联接将排除不匹配的MatchItems,但我们需要知道匹配集中有多少IsNeg=0的MatchItems,以确保它们都满足要求。我们可以在不使用其他联接的情况下使用分区计数吗?
SELECT DISTINCT matchset,
              visit_id,
              tgtcount,
              match_visit_count,
              isneg_sum
              GpMatchItems.count tgtCount 
FROM 
             COUNT (*) OVER (PARTITION BY MatchItems.MatchSet, DataValues.Visit_id)
                 AS match_visit_count,
             SUM (MatchItems.IsNeg) OVER (PARTITION BY MatchItems.MatchSet, DataValues.Visit_id)
                 AS isneg_sum
        FROM DataValues 
        LEFT JOIN MatchItems ON MatchItems.VALUE = DataValues.VALUE)
        LEFT JOIN ( SELECT 
                     MatchItems.MatchSet,
                     count(*) Count
                 FROM MatchItems
                 WHERE MatchItems.IsNeg = 0
                 GROUP BY
                     MatchItems.MatchSet) GpMatchItems 
                 ON GpMatchItems.MatchSet = MatchItems.MatchSet
         )
WHERE 
tgtcount = match_visit_count 
AND isneg_sum = 0;