2017-06-19 851 views
1

我正在研究涉及单词及其翻译的项目。一个查询翻译必须频繁任务(每10秒一次左右)的是:SQL使用LEFT JOIN优化“IS NULL”查询

SELECT * FROM pwords p 
LEFT JOIN words w ON p.id = w.wordid 
WHERE w.code IS NULL 
OR (w.code <> "USER1" AND w.code <> "USER2") 
ORDER BY rand() LIMIT 10 

要接收一个字翻译,该用户尚未翻译。在这种情况下,我们想禁止USER2输入的文字

pwords表大约有66k条目,单词表大约有55k条目。

该查询大约需要500秒才能完成,而如果我删除了IS NULL,则查询需要0.0245 ms。我的问题在于:有没有一种方法来优化此查询?我真的需要挤压数字。

这种情况是:USER1不希望来自USER2的单词表中的任何数据库条目。它不需要来自同一个表的自己的数据库条目。因此,我需要使用IS NULL或类似方法从除USER1和USER2以外的所有用户(其他用户或NULL条目)获取条目。

tl; dr所以我的问题是:有没有办法让这个查询运行得更快? “IS NULL”是否可优化?

任何和所有的帮助,非常感谢。

回答

0

你可以尝试以过滤行使用子查询(用WHERE语句)尽快:

SELECT * 
FROM pwords p 
LEFT JOIN 
    (SELECT * 
    FROM words w 
    WHERE (w.code <> "USER1" AND w.code <> "USER2")) subq 
ON p.id = subq.wordid 
WHERE w.code IS NULL 
ORDER BY rand() LIMIT 10 

另一个(也许更有效的选择)用NOT EXISTS声明:

SELECT * 
FROM pwords p 
WHERE NOT EXISTS 
    (SELECT * 
    FROM words w 
    WHERE p.id=w.wordid AND (w.code <> "USER1" AND w.code <> "USER2")) 
ORDER BY rand() LIMIT 10 
+1

得到的查询降到0.1326左右。非常感谢你!如果可以的话,我会让你满意!也感谢你教我关于子查询,作为一个我以前从未遇到过的业余爱好者。 – deFunc

+0

您仍然可以将其标记为正确的答案:) 有关MySQL中子查询的更多信息,请访问:https://dev.mysql.com/doc/refman/5.7/en/subqueries.html – Dimgold