C# 计算未出现在其他表中的元素数的最佳方法
考虑以下情况C# 计算未出现在其他表中的元素数的最佳方法,c#,mysql,query-performance,C#,Mysql,Query Performance,考虑以下情况 TableA TableB +------------+----------+----------+----------+ +---------+ |Column1 | Column2 | Column3 | Column4 | | entB | +-----------------------+----------+---------
TableA TableB
+------------+----------+----------+----------+ +---------+
|Column1 | Column2 | Column3 | Column4 | | entB |
+-----------------------+----------+----------+ +---------+
| zzzxxxx | NULL | NULL | zzzyyyy | | zzzxxxx |
+------------+----------+----------+----------+ +---------+
| zzzqqqq | NULL | SomeText | NULL | | zzzyyyy |
+------------+----------+----------+----------+ +---------+
| NULL | zzzxxxx | zzzxxx | NULL | | zzzwwww |
+------------+----------+----------+----------+ +---------+
| zzzyyyy | zzzyyyy | zzzwwww | SomeText |
+------------+----------+----------+----------+
其中z,y,x=1-9,某些文本可以包含任何数字或字母-表B的ent B列中不能有空值
我需要找到表A中不在表B中的值的总数。表A中的列不包含唯一(不同)值,并且可能为空
我的第一次尝试是以下和查询
$"select count(1) from " +
$"(" +
$" select distinct Column1 from {TableA} where Column1 not in (select entB from {TableB})" +
$" union" +
$" select distinct Column2 from {TableA} where Column2 not in (select entB from {TableB})" +
$" union" +
$" select distinct Column3 from {TableA} where Column3 not in (select entB from {TableB})" +
$" union" +
$" select distinct Column4 from {TableA} where Column4 not in (select entB from {TableB})" +
$") as t"
这很好,直到我不得不在一个有7000000行和100000行的TableB表上进行测试,而TableB的查询需要很长时间才能执行。我正在寻找减少时间的方法
我读到使用Distinct
和Union
是一种降低性能的简单方法,所以我想试试这样的方法
SELECT Column1
FROM TableA a
WHERE NOT EXISTS (SELECT 1 FROM TableB b WHERE a.Column1 = b.entB and a.Column1 is not null )
and Column1 is not null)
获取结果,将其保存在DataTable中,然后对其他3列重复相同的查询,并合并检查内存中重复项的结果
你知道有没有更好的解决办法吗
编辑:我编辑了表格,以便更好地显示我的数据。在这个例子中,我希望结果是值“2”,因为有两个值(SomeText和zzzqqq)不存在于表B中一旦我们克服了所有关于
表A
如何未规范化的抱怨,这并不难做到
我猜您需要统计表a中与表B不匹配的四列的值。如果你想要更复杂的东西,恕我直言,花点时间想清楚如何准确地描述它
从一个子查询开始,该子查询提供要比较的表a
中的值。因为我们使用UNION
而不是UNION ALL
,所以我们可以免费获得SELECT DISTINCT
。(SQL操作集合。)
然后,使用左连接。。。。为空
模式以获取不匹配的项
SELECT COUNT(*) number_of_unmatched_items
FROM ( SELECT Column1 AS ent FROM TableA
UNION
SELECT Column2 AS ent FROM TableA
UNION
SELECT Column3 AS ent FROM TableA
UNION
SELECT Column4 AS ent FROM TableA
) a
LEFT JOIN TableB b ON a.ent = b.entB
WHERE b.entB IS NULL
WHERE…为NULL
从子查询中拾取在左联接中未满足ON
条件的行
为了使这个过程非常快,我认为您需要在涉及到的TableA
中的每一列上分别建立索引,以及在TableB
中的entB
上建立索引。但是您需要尝试一下,如果它仍然不能满足您的性能需求,请进行解释
除非运行MySQL的机器真的缺少RAM,否则MySQL应该合理有效地处理这些事情
专业提示:您已经知道这一点。像TableA
这样的非规范化表确实会扰乱查询性能。一旦我们克服了所有关于TableA
如何未规范化的抱怨,这并不难做到
我猜您需要统计表a中与表B不匹配的四列的值。如果你想要更复杂的东西,恕我直言,花点时间想清楚如何准确地描述它
从一个子查询开始,该子查询提供要比较的表a
中的值。因为我们使用UNION
而不是UNION ALL
,所以我们可以免费获得SELECT DISTINCT
。(SQL操作集合。)
然后,使用左连接。。。。为空
模式以获取不匹配的项
SELECT COUNT(*) number_of_unmatched_items
FROM ( SELECT Column1 AS ent FROM TableA
UNION
SELECT Column2 AS ent FROM TableA
UNION
SELECT Column3 AS ent FROM TableA
UNION
SELECT Column4 AS ent FROM TableA
) a
LEFT JOIN TableB b ON a.ent = b.entB
WHERE b.entB IS NULL
WHERE…为NULL
从子查询中拾取在左联接中未满足ON
条件的行
为了使这个过程非常快,我认为您需要在涉及到的TableA
中的每一列上分别建立索引,以及在TableB
中的entB
上建立索引。但是您需要尝试一下,如果它仍然不能满足您的性能需求,请进行解释
除非运行MySQL的机器真的缺少RAM,否则MySQL应该合理有效地处理这些事情
专业提示:您已经知道这一点。像TableA
这样的非规范化表确实会影响查询性能。您似乎有几个column2。因此,这个问题是无法理解的。请看:@草莓这是一个明显的打字错误,而试图格式化的问题。。。现在已经解决了这类问题,这是糟糕的模式设计的严重症状。考虑是否有修改的范围。使用左外部连接。项目数默认为空。请参阅:@jdweng DefaultEmpty应该在我执行了4个查询后在我的代码中使用?您似乎有几个column2。因此,这个问题是无法理解的。请看:@草莓这是一个明显的打字错误,而试图格式化的问题。。。现在已经解决了这类问题,这是糟糕的模式设计的严重症状。考虑是否有修改的范围。使用左外部连接。项目数默认为空。请参阅:@jdweng DefaultEmpty应该在我执行了4个查询后在我的代码中使用?endB
最好是表b
中某个索引的开头。不过,查询可能需要几个小时,因为它需要对7000万行进行4次表扫描;再加上对较小的表进行4*70M的查找。我想让您知道,您的解决方案,至少在我的环境中是最慢的。我提出的第一个查询需要约5分钟才能执行,而不存在的版本需要约2分钟半。您的查询需要27分钟才能完成。建议将UNION
更改为UNION DISTINCT
,因为查询中包含的算法依赖于重复数据。endB
最好是表b
中某些索引的开始。不过,查询可能需要几个小时,因为它需要对7000万行进行4次表扫描;再加上对较小的表进行4*70M的查找。我想让您知道,您的解决方案,至少在我的环境中是最慢的。我提出的第一个查询需要约5分钟才能执行,而不存在的版本需要约2分钟半。您的查询需要27分钟才能完成。建议将UNION
更改为UNION DISTINCT
,因为