我有一些麻烦与执行自连接在一个子查询,它需要比我想象它应该和我有一些认识问题,为什么更多的时间查询。自加入重复检测
的问题如下,业主可以有项目,但某些项目可能会出现两次属于不同的所有者,从每个业主,我们可能得到关于项目的信息稍有不同,或某些字段可能为空。
这是我的数据库的简单版本,它不包含FK和索引,只有当他们出现存在IdOwner,IdItem和IdCategry。
业主:
+----------------+---------------+------+-----+
| Field | Type | Null | Key |
+----------------+---------------+------+-----+
| IdOwner | bigint(20) | NO | PRI |
| IdPlace | int(10) | NO | |
| SomeDate | datetime | YES | |
+----------------+---------------+------+-----+
项目:
+----------------+---------------+------+-----+
| Field | Type | Null | Key |
+----------------+---------------+------+-----+
| IdItem | bigint(20) | NO | PRI |
| IdOwner | bigint(20) | NO | MUL |
| IdCategory | int(10) | NO | |
| DupValue1 | varchar() | YES | |
.
.
.
| DupValueN | varchar() | YES | |
+----------------+---------------+------+-----+
国家:
+----------------+---------------+------+-----+
| Field | Type | Null | Key |
+----------------+---------------+------+-----+
| IdOwner | bigint(20) | NO | PRI |
| Country | Varchar() | NO | PRI |
+----------------+---------------+------+-----+
DupValues 1到N是我发现的列具有最大概率是当物品重复时也是如此。
这是我目前正与查询的简化版本:
SELECT subquery1.IdItem, subquery2.IdItem FROM
(SELECT i1.IdCategory, i1.IdOwner, i1.IdItem, i1.DupValue1, o1.IdSite, o1.SomeDate, COUNTRY.country
FROM ITEMS i1
LEFT JOIN OWNER o1 ON o1.IdOwner=i1.IdOwner
LEFT JOIN COUNTRY ON i1.IdOwner=COUNTRY.IdOwner
WHERE i1.IdOwner>9000000)
as subquery1
INNER JOIN
(SELECT i2.IdCategory, i2.IdOwner, i2.IdItem, i2.DupValue1, o2.IdSite, o2.SomeDate, COUNTRY.country
FROM ITEMS i2
LEFT JOIN COUNTRY COUNTRY ON i2.IdOwner=COUNTRY.IdOwner
LEFT JOIN OWNER o2 ON o2.IdOwner=i2.IdOwner
WHERE i2.IdOwner>9000000)
as subquery2
ON subquery1.IdItem<subquery2.IdItem
AND subquery1.IdCategory=subquery2.IdCategory
AND subquery1.IdSite!=subquery2.IdSite AND subquery1.country=subquery2.country
AND DATE(subquery1.SomeDate)=DATE(subquery2.SomeDate)
AND (subquery1.DupValue1=subquery2.DupValue1 OR subquery1.DupValue1 IS NULL OR subquery2.DupValue1 IS NULL)
还有一些更SupValue都具有相同的格式。
WHERE子句用于限制拥有者数量,因为我仍然在测试查询,当WHERE子句已经到位时,它将拥有者限制在约700,000行,并且拥有该行数的行数约为30分钟过程。
当我使用的查询说明我得到这个:
+------+-------------+---------+--------+----------------------------------------+-------------+---------+------------------------+-------+------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+---------+--------+----------------------------------------+-------------+---------+------------------------+-------+------------------------------------+
| 1 | SIMPLE | i1 | range | PRIMARY,UnivocID,dg_owner,dg_category | UnivocID | 8 | NULL | 19056 | Using index condition |
| 1 | SIMPLE | o1 | eq_ref | PRIMARY | PRIMARY | 8 | i1.IdTender | 1 | |
| 1 | SIMPLE | country | ref | PRIMARY | PRIMARY | 8 | i1.IdTender | 1 | Using index |
| 1 | SIMPLE | i2 | ref | PRIMARY,UnivocID,dg_owner,dg_category | dg_category | 4 | i1.IdMolecule | 657 | Using index condition; Using where |
| 1 | SIMPLE | o2 | eq_ref | PRIMARY | PRIMARY | 8 | i2.IdTender | 1 | Using where |
| 1 | SIMPLE | country | ref | PRIMARY | PRIMARY | 8 | i2.IdTender | 1 | Using index |
+------+-------------+---------+--------+----------------------------------------+-------------+---------+------------------------+-------+------------------------------------+
MariaDB的版本:10.1
我的2个问题:
¿是否subquery2
为subquery1
每一行执行和这是什么原因造成的执行时间是长还是这ON
条款,有过错的性质是什么?
¿可以查询被提高,也许开沟赞成JOIN
或其他运营商?
您是否需要子查询,或者是否可以直接在没有子查询的情况下完成(如果在完整查询中在其中具有聚合函数,则可能需要子查询)。 – Kickstart
@Kickstart我需要子查询,因为我需要从3个表中的数据到1,然后我需要对结果表进行操作来检测重复项,做内部连接是我知道这样做的唯一方法。 –
可能的问题是您正在使用LEFT OUTER JOINs,因此一些返回的字段可能为NULL。而NULL不等于NULL(但你加入基于国家字段是相等的)。如果你的子查询的效果超过了LEFT OUTER JOINs,但结果被处理的方式将意味着结果可能来自INNER JOINs – Kickstart