在任何合理的运行时间努力获得这个。我有三张桌子:
temp_company
公司
company_scode
我需要将temp_company表与number字段上的company表匹配,然后我想检查company_scode表中公司是否存在临时表中的s_code,如果它没有选择那个行。
到目前为止,我有:
SELECT temp_company.s_code
FROM temp_company
WHERE temp_company.s_code NOT IN
(SELECT code
FROM company
LEFT JOIN company_scode ON company.id = company_scode.company_id
WHERE
company.number = temp_company.number
)
但这非常慢,我希望有一种更好的方法来选择每个temp_company记录,其中s_code在公司和company_scode之间的多对多关系中不存在。
*更新 *
感谢Loc和Ollie的答案,这些仍然需要很长时间(我离开Ollie已经8个小时了,而且还在继续)。
就索引而言,我已在上面更新了信息。我已经将下面的解释放在了两个答案中,试图揭开一些亮点,希望能更快地实现这一点。
解答奥利的答案:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | extra |
+----+--------------------+------------+-------+---------------+------------+---------+-----------------------+---------+--------------------------+
| 1 | PRIMARY | tc | ALL | (NULL) | (NULL) | (NULL) | (NULL) | 3216320 | |
+----+--------------------+------------+-------+---------------+------------+---------+-----------------------+---------+--------------------------+
| 1 | PRIMARY | <derived2> | ALL | (NULL) | (NULL) | (NULL) | (NULL) | 2619433 | Using where; Not exists |
+----+--------------------+------------+-------+---------------+------------+---------+-----------------------+---------+--------------------------+
| 2 | DERIVED | s | index | company_id | code | 62 | (NULL) | 2405379 | Using index |
+----+--------------------+------------+-------+---------------+------------+---------+-----------------------+---------+--------------------------+
| 2 | DERIVED | c | eq_ref| PRIMARY | PRIMARY | 4 | mydbname.s.company_id | 1 | |
+----+--------------------+------------+-------+---------------+------------+---------+-----------------------+---------+--------------------------+
解答Loc的答案:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | extra |
+----+--------------------+-------+-------+---------------+------------+---------+---------------+---------+--------------------------+
| 1 | PRIMARY | tc | ALL | (NULL) | (NULL) | (NULL) | (NULL) | 3216320 | Using where |
+----+--------------------+-------+-------+---------------+------------+---------+---------------+---------+--------------------------+
| 2 | DEPENDENT SUBQUERY | c | index | (NULL) | number | 63 | (NULL) | 3189756 | Using where; Using index |
+----+--------------------+-------+-------+---------------+------------+---------+---------------+---------+--------------------------+
| 2 | DEPENDENT SUBQUERY | cc | ref | company_id | company_id | 4 | mydbname.c.id | 1 | Using where; Using Index |
+----+--------------------+-------+-------+---------------+------------+---------+---------------+---------+--------------------------+
答案 0 :(得分:1)
测试这个:
SELECT tc.*
FROM temp_company tc
WHERE NOT EXISTS
(
SELECT 1
FROM company c LEFT JOIN company_scode cc ON c.id = cc.company_id
WHERE c.number = tc.number
)
答案 1 :(得分:1)
这种方式可能比嵌套的SELECT快得多。
SELECT tc.id, tc.number, tc.s_code
FROM temp_company AS tc
LEFT JOIN (
SELECT s.code AS company_scode,
c.id
FROM company AS c
JOIN company_scode AS s ON c.id = s.code
) AS existing_company
ON ( tc.scode = existing_company.company_scode
AND tc.id = existing_company.id)
WHERE existing_company.company_scode IS NULL
这可以通过运行返回(id,scode)列表的子查询来实现。然后它将它连接到temp_company表并使用IS NULL查找仅出现在连接左侧的项目。
答案 2 :(得分:0)
最后,我将这一点降低到大约1分钟的可管理时间,其中包括以下内容:
CREATE TEMPORARY TABLE tc AS
(SELECT company.id AS cid, temp_company.scode AS tcode
FROM temp_company
INNER JOIN company ON temp_company.number = company.number
WHERE temp_company.scode IS NOT NULL AND temp_company.scode != "")
CREATE TEMPORARY TABLE rc AS
(SELECT tc.cid as cid FROM tc
LEFT JOIN company_scode ON tc.cid = company_scode.company_id
WHERE tc.tcode = company_scode.code)
SELECT * FROM tc
WHERE tc.cid NOT IN (SELECT cid FROM rc)
我宁愿不使用临时表,所以如果有人在类似或更快的时间内发布解决方案,那么我很乐意更新答案。