Mysql 提高速度非常慢的最佳选择';相关项目';查询

Mysql 提高速度非常慢的最佳选择';相关项目';查询,mysql,sql,Mysql,Sql,我有两个表,一个是图像,另一个是描述哪些用户喜欢哪些图像。第二个表只是每个图像/用户组合有一行。我想写一个查询,它将返回数据库中的哪些其他图像有尽可能多的共同点。因此,这些表看起来像: images +----+----------+ | id | filename | +----+----------+ images_users +----------+---------+ | image_id | user_id | +----------+---------+ 我的问题是: SELEC

我有两个表,一个是图像,另一个是描述哪些用户喜欢哪些图像。第二个表只是每个图像/用户组合有一行。我想写一个查询,它将返回数据库中的哪些其他图像有尽可能多的共同点。因此,这些表看起来像:

images
+----+----------+
| id | filename |
+----+----------+

images_users
+----------+---------+
| image_id | user_id |
+----------+---------+
我的问题是:

SELECT images.filename FROM 
  images_users INNER JOIN images ON images.id = images_users.image_id 
   WHERE images_users.user_id IN ( .... list of user IDs ....) 
   AND NOT images.id = <current image id>
  GROUP BY images.id ORDER BY COUNT(images.id) DESC LIMIT 10;
在images_users表中有大约10000个用户、大约150万个图像和大约600万行

图形数据库就是答案 我在这里回答我自己的问题,因为我接受了@Jason的评论,跟踪了neo4j的链接,安装了它,学习了它优秀的查询语言Cyper和bam。问题解决了

我收集了我所有的数据,两百万张图片和一千万条关系,然后把它们推到neo4j中。首先,我创建了索引

CREATE INDEX ON :Image(filename)
CREATE INDEX ON :User(name)
然后对用户和图像之间的每个关系运行以下查询。如果用户和图像还不存在,这也会为用户和图像创建节点

MERGE (i:Image{filename:'...'})
MERGE (u:User{name:'...'})
CREATE (u)-[:LIKES]->(i)
这有点慢,我确实在某种程度上改进了导入过程,但得到的数据是相同的。然后,搜索的查询变为

MATCH (n:Image{filename:'...'})<-[]-(u:User)-[l]->(i:Image) 
WITH count(l) AS c, i.filename AS f 
ORDER BY c DESC LIMIT 10
MATCH(n:Image{filename:'.'.'})(i:Image)
计数(l)为c,i.filename为f
按c描述订购限制10
在任何情况下,这都是一种更具表现力的编写查询的方式,并且运行速度比同等的MySQL查询快一个数量级,MySQL查询上存在所有适当的索引

其他的查询也会以非常昂贵的连接而告终,比如show me all images with than five like,效率极高

MATCH (n:Image) where size ( (n)<-[]-() ) > 3 return n.filename 
LIMIT 20
匹配(n:Image),其中size((n)3返回n.filename
限制20
图形数据库就是答案 我在这里回答我自己的问题,因为我接受了@Jason的评论,跟踪了neo4j的链接,安装了它,学习了一点它优秀的查询语言Cyper和bam。问题解决了

我收集了我所有的数据,200万张图片和1000万条关系,并将它们放入neo4j。首先,我创建了索引

CREATE INDEX ON :Image(filename)
CREATE INDEX ON :User(name)
然后对用户和映像之间的每个关系运行以下查询。这还会在用户和映像运行时为它们创建节点(如果它们不存在)

MERGE (i:Image{filename:'...'})
MERGE (u:User{name:'...'})
CREATE (u)-[:LIKES]->(i)
这有点慢,我确实在某种程度上改进了导入过程,但生成的数据是相同的

MATCH (n:Image{filename:'...'})<-[]-(u:User)-[l]->(i:Image) 
WITH count(l) AS c, i.filename AS f 
ORDER BY c DESC LIMIT 10
MATCH(n:Image{filename:'.'.'})(i:Image)
计数(l)为c,i.filename为f
按c描述订购限制10
在任何情况下,这都是一种更具表现力的编写查询的方式,并且运行速度比同等的MySQL查询快一个数量级,MySQL查询上存在所有适当的索引

其他的查询也会以非常昂贵的连接而告终,比如show me all images with than five like,效率极高

MATCH (n:Image) where size ( (n)<-[]-() ) > 3 return n.filename 
LIMIT 20
匹配(n:Image),其中size((n)3返回n.filename
限制20

马上,您所做的似乎更适合使用图形数据库来保存和挖掘这些关系。也就是说,您可以尝试一个将用户id映射到图像id的表,这样您就可以更容易地找到特定用户的图像。我怀疑图像比用户多。我很想看看t的解释输出是什么hat query可能会显示什么?@Jason,我该如何构建一个图形数据库?我会假设我的images_users表可以很容易地找到用户喜欢的图像?当我说graph database时,我想到的是Neo4j之类的东西。它们更适合于这些类型的关系。至于images_users表,如果你想到图像数量与用户数量之比,您必须搜索大量图像才能找到这些特定的用户。如果在重复的表中颠倒关系,则相比之下,您应该有较少的用户进行搜索,并且您将首先搜索该用户,然后再查找该用户的图像(如果有意义)。@Jason,我将介绍图形数据库的概念,但我认为images_users表已经表达了两个方向的关系,不是吗?最终看来,使用关系数据库似乎是一项艰巨的工作。一方面,您所做的似乎更适合使用图形数据库来保存和挖掘这些关系。也就是说,y你可以尝试一个将user_id映射到image_id的表,这样你就可以更容易地找到特定用户的图像。我怀疑图像比用户多。我很想看看该查询的解释输出可能会显示什么?@Jason,我该如何构建图形数据库?我会假设我的images_users表为finds用户已经足够喜欢的图像?当我说graph database时,我想到的是Neo4j之类的东西。它们更适合于这些类型的关系。至于images_users表,如果你考虑到图像的数量与用户的数量,你将不得不搜索大量图像来找到那些特定的用户。如果你将relati在一个重复的表中登录时,相比之下,您应该有较少的用户进行搜索,您将首先搜索该用户,然后找到该用户的图像(如果有意义的话)。@Jason,我将研究图形数据库的概念,但我认为images\u users表以两种方式表达了关系离子已经存在了,不是吗?归根结底,这似乎只是关系数据库的一项重要工作。