1

此查询工作正常,但执行时间过长。它在 xampp localhost 上运行。

只是我想选择webpage.id where word= "somthing" AND word != " another somthing"

我的意思是,如果您在 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

这是创建脚本是否有任何优化?

提前致谢。

4

4 回答 4

0

您可能想考虑一个沿着这些思路的解决方案- 几个月前由另一个论坛中的某个人(我知道,我知道)提供。

此外,查询的第一部分会更有意义(无论如何对我来说)这样写(注意没有 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"
于 2013-05-15T23:42:58.563 回答
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

---- --------
| 编号 | 标题 |
 ---- --------
| 1 | 游戏 |
| 2 | 爪哇 |
| 3 | 蟒蛇 |
| 4 | 猫 |
 ---- --------

se_webpage

---- ------ ------------ ------ ---------
| 编号 | 链接 | 标题 | 频率 | 日期 |
 ---- ------ ------------ ------ ---------
| 1 | 空 | aaaaa.com | 0 | 2013-05-15 22:27:40 |
| 2 | 空 | bbbbb.com | 0 | 2013-05-15 22:27:40 |
| 3 | 空 | ccccc.com | 0 | 2013-05-15 22:27:40 |
| 4 | 空 | ddddd.com | 0 | 2013-05-15 22:27:40 |
 ---- ------ ------------ ------ ---------

se_wordpage

---- -------- -------- ------
| 编号 | 字号 | 页ID | 类型 |
 ---- -------- -------- ------
| 1 | 3 | 1 | |
| 2 | 3 | 2 | |
| 3 | 3 | 3 | |
| 4 | 3 | 4 | |
| 5 | 4 | 2 | |
| 6 | 4 | 4 | |
 ---- -------- -------- ------

由于“ python ”一词是指所有网页,而“ cat ”一词是指第二个和第四个网页,因此预期的输出(据我所知)应该是第一个和第三个网页(带有更多数据)。所以,查询效果很好!

输出

------------ -------- ---- ------------ ---- ------ ------ -- ---- ------ --------
| 标题 | 标题 | 编号 | 标题 | 编号 | 链接 | 字号 | 编号 | 类型 | 页ID |
 ------------ -------- ---- ------------ ---- ------ ------ -- ---- ------ --------
| ccccc.com | 蟒蛇 | 3 | ccccc.com | 3 | 空 | 3 | 3 | | 3 |
| aaaaa.com | 蟒蛇 | 3 | aaaaa.com | 1 | 空 | 3 | 1 | | 1 |
 ------------ -------- ---- ------------ ---- ------ ------ -- ---- ------ --------

查看列的顺序与查询语句中的顺序相同。

让我知道是否有问题。

于 2013-05-16T00:02:57.140 回答
0

使用“不在”很慢。如果您的数据库支持这里的语法,则有两种更快的方法。

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
)

对于某些数据库引擎,您使用关键字“minus”而不是“except”。

于 2013-05-15T23:24:29.167 回答
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
于 2013-05-15T23:24:30.960 回答