此查询工作正常,但执行时间过长。它在xampp localhost上运行。
我只想选择webpage.id,其中word =“somthing”和word !=“另一种东西”
我的意思是,如果您在Google上搜索,则可以使用该快捷方式 “python -cat” 这意味着获取包含单词“python”且不包含单词“cat”的所有链接。
SELECT webpage.title, word.title, word.id, webpage.title, webpage.id, webpage.link, wordpage.wordID, wordpage.id, wordpage.type, wordpage.pageID
FROM SE_word AS word
INNER JOIN se_wordpage AS wordpage ON wordpage.wordID = word.id
INNER JOIN se_webpage AS webpage ON wordpage.pageID = webpage.id
WHERE word.title = "python"
AND webpage.id NOT IN (
SELECT WP.id
FROM se_webpage AS WP
INNER JOIN se_wordpage AS WOP ON WP.id = WOP.pageID
INNER JOIN se_word AS W ON W.id = WOP.wordID
WHERE W.title = "cat"
)
GROUP BY webpage.id
ORDER BY webpage.title DESC
这是一个简单的搜索引擎,例如
table se_Word is
**id | title**
1 | "game"
2 | "java"
3 | "python"
table se_WebPage is
**id | title**
1 | "www.ABCDEF.com"
2 | "www.ABCDR.net"
3 | "www.ABC.com"
table se_WordPage is
**id | pageID | wordID**
1 | 1 | 1
2 | 2 | 3
3 | 3 | 3
3 | 2 | 1
结果应为webpage.id = 3
here is创建脚本 对它有任何优化吗?
提前致谢。
答案 0 :(得分:0)
使用“not in”很慢。如果您的数据库支持语法,则有两种更快的方法。
where not exists
(your subquery)
或
where webpage.id in
(select id
from se_webpage
except
select id
from
the rest is as per your existing subquery
)
对于某些数据库引擎,您使用关键字“减号”而不是“除”。
答案 1 :(得分:0)
我认为如果你能摆脱NOT IN片段那么你应该看到健康的性能提升。尝试使用这两个等效语句作为如何重写语句的示例。
声明1:
select ID, PreferredMethods
from ContactPrefs
where type='Mail' and
ID NOT IN
(select ID from ContactPrefs where type='Email' or type='Phone' or type='Text')
声明1相当于声明2,但声明2的表现会更好:
select ID, PreferredMethods from ContactPrefs c1
left outer join
ContactPrefs c2 on c1.ID=c2.ID
and (c2.type='Email' or c2.type='Phone' or c2.type='Text')
where c1.type='Mail' and c2.id is null
答案 2 :(得分:0)
你可能想考虑these lines之前的解决方案 - 几个月前由不同论坛的人(我知道,我知道)完全提供。
此外,你的查询的第一部分会更有意义(对我而言)就像这样(注意缺少GROUP BY子句 - 这是故意的)...
SELECT DISTINCT p.title p_title
, w.title w_title
, w.id w_id
, p.id p_id
, p.link
, wp.id
, wp.type
FROM SE_word w
JOIN se_wordpage wp
ON wp.wordID = w.id
JOIN se_webpage p
ON p.id = wp.pageID
WHERE w.title = "python"
答案 3 :(得分:0)
我没有测试过这个查询,但我认为它可以完成这项工作。如果它没有错误,请告诉我。
根据您的原始查询,我刚删除了子查询,在WHERE
子句中添加了“cat”标题,并添加了HAVING
子句,以便在GROUP BY
网页之后进行过滤只选择了一次,这个选择引用了“python”标题。
我假设你从不多次将一个给定的单词分配给一个给定的网页。
SELECT
webpage.title,
word.title,
word.id,
webpage.title,
webpage.id,
webpage.link,
wordpage.wordID,
wordpage.id,
wordpage.type,
wordpage.pageID
FROM se_word AS word
INNER JOIN se_wordpage AS wordpage
ON wordpage.wordID = word.id
INNER JOIN se_webpage AS webpage
ON wordpage.pageID = webpage.id
WHERE word.title IN ("cat", "python")
GROUP BY webpage.id
HAVING
COUNT(webpage.id) = 1
AND word.title = "python"
ORDER BY webpage.title DESC;
希望它运作良好并帮助你!再见。
修改强>
我测试了我的查询(MySQL 5.5.22),它似乎工作正常!这是我的表结构和数据:
表 se_word :
---- -------- | id | title | ---- -------- | 1 | game | | 2 | java | | 3 | python | | 4 | cat | ---- --------
表 se_webpage :
---- ------ ----------- ------ --------------------- | id | link | title | freq | date | ---- ------ ----------- ------ --------------------- | 1 | NULL | aaaaa.com | 0 | 2013-05-15 22:27:40 | | 2 | NULL | bbbbb.com | 0 | 2013-05-15 22:27:40 | | 3 | NULL | ccccc.com | 0 | 2013-05-15 22:27:40 | | 4 | NULL | ddddd.com | 0 | 2013-05-15 22:27:40 | ---- ------ ----------- ------ ---------------------
表 se_wordpage :
---- -------- -------- ------ | id | wordID | pageID | type | ---- -------- -------- ------ | 1 | 3 | 1 | | | 2 | 3 | 2 | | | 3 | 3 | 3 | | | 4 | 3 | 4 | | | 5 | 4 | 2 | | | 6 | 4 | 4 | | ---- -------- -------- ------
由于“ python ”一词指的是所有网页,而“ cat ”一词指的是第二和第四个网页,预期输出(就我而言)理解)应该是第一个和第三个网页(有一些更多的数据)。所以,查询效果很好!
输出:
----------- -------- ---- ----------- ---- ------ -------- ---- ------ -------- | title | title | id | title | id | link | wordID | id | type | pageID | ----------- -------- ---- ----------- ---- ------ -------- ---- ------ -------- | ccccc.com | python | 3 | ccccc.com | 3 | NULL | 3 | 3 | | 3 | | aaaaa.com | python | 3 | aaaaa.com | 1 | NULL | 3 | 1 | | 1 | ----------- -------- ---- ----------- ---- ------ -------- ---- ------ --------
查看列的顺序与查询语句中的顺序相同。
如果出现问题,请告诉我。