【发布时间】:2016-06-08 22:09:24
【问题描述】:
我有两张桌子 - books 和 images。 books 具有 id、name、releasedate、purchasecount 等列。 images有bookid(和书本里的id一样,基本上一本书可以有多张图片,虽然我没有设置外键约束),bucketid,poster(每条记录点到某个桶中的一个图像文件,对于某个bookid)。
表架构:
-
poster在images中是唯一的,因此它是主键。 - 书籍封面索引:(
name,id,releasedate) - 图片覆盖索引:(
bookid,poster,bucketid)
我的查询是,给定一个名称,从 books 表中找到名称与该名称匹配的前十本书(按purchasecount 的数量排序),并为该书返回任何(最好是第一条)记录(@ 987654344@ 和 poster) 来自 images 表。
显然这可以通过运行第一个查询并使用其结果查询图像表来解决这两个查询,但这会很慢,所以我想使用'join'和子查询一次性完成。但是,我正在尝试并没有给我正确的结果:
select books.id,books.name,year(releasedate),purchasecount,bucketid,poster from books
inner join (select bucketid,bookid, poster from images) t on
t.bookid = books.id where name like "%foo%" order by purchasecount desc limit 2;
任何人都可以在这里根据需要提出最佳查询来获取结果集(包括更改表架构以缩短搜索时间的任何建议)吗?
更新小提琴:http://sqlfiddle.com/#!9/17c5a8/1.
示例查询应返回两个结果 - fooe 和 fool,以及每个结果的一个(对应于每本书的多个海报中的任何一个)海报。但是我没有得到正确的结果。预期:
fooe - 1973 - 459 - 11 - swt(或fooe - 1973 - 459 - 11 - pqr)
fool - 1963 - 456 - 12 - xxx(或fool - 1963 - 456 - 111 - qwe)
【问题讨论】:
-
海报是独一无二的吗?什么是海报?
-
图像文件名。所有图像都位于同一个存储桶中,因此名称必须是唯一的。
-
即使世界上最好的意愿,文件名也可以更改。这不是一个好的主键
-
文件名由第 3 方 API 生成,并保证是唯一的。另外,在插入存储桶之前,会进行额外的检查以查看是否存在该名称的此类文件,在这种情况下生成另一个名称(并继续),直到生成唯一的名称,然后将其转储到存储桶中。我们可能还需要通过图像名称进行查询(例如该图像有多少“喜欢”),因此是主键,而不是为其创建另一个唯一的 id,因为它无论如何都保证是唯一的。
-
我们喜欢在文本和示例数据中使用模式的问题。一个 sqlfiddle 很棒。否则我们经常逃跑。当你已经拥有它时,你是在要求别人把它敲出来。
标签: mysql subquery query-optimization inner-join mysql-variables