标题真的不够解释...
我每小时运行一次查询以准备 MEMORY 表,然后将这些表用于下一小时的一些高强度流量。现在查询看起来像:
INSERT INTO tmp_table
SELECT DISTINCT SQL_NO_CACHE
B.*, G.node
FROM books B
RIGHT JOIN book_genres G on G.asin=B.asin
WHERE EXISTS
(
SELECT 1 FROM genres K WHERE K.node=G.node
)
AND...[nothing special here]
因此,books 表只保存带有 asin 的 PRIMARY KEY 的书籍数据。book_genres 包含 asin 和 node 字段,并包含许多用于站点各个部分的节点。然而,tmp_table 只需要包含流派表中的节点子集,因此是子查询。希望这在不发布完整架构的情况下就足够了。
我们现在想让某些类型相互排斥。这意味着在构建 tmp_table 之后执行此操作:
# Delete records that should have been excluded
DELETE T FROM tmp_table T INNER JOIN
(
SELECT N.* FROM tmp_table N INNER JOIN
(
SELECT DISTINCT ASIN FROM tmp_table
INNER JOIN genres ON genres.node=tmp_table.node
WHERE isFiction=1
) F
ON F.asin=N.asin
INNER JOIN genres ON genres.node=N.node
WHERE genres.isNonFiction=1
) D
USING (asin, node)
WHERE D.asin=T.asin AND D.node=T.node
因此,如果该 asin 属于 isFiction=1 的流派,则将删除所有 nonFiction=1 的流派。
但这感觉很难看:使用查询添加数据,然后再次删除它。有什么方法可以将其组合成一个查询以避免双重传递。或者我只是在为自己工作,考虑到(经过一些调整和编辑)上面的工作确实很快就可以接受。
任何想法将不胜感激,谢谢。
添加示例:
books table:
asin title price etc...
B111111111 Book1 $0.99 ....
B222222222 Book2 $0.99 ....
B333333333 Book2 $0.99 ....
book_genres table:
asin node
B111111111 1111
B111111111 2222
B111111111 3333
B111111111 5555
B222222222 1111
B222222222 3333
B222222222 4444
B333333333 1111
B333333333 2222
genres table:
node name isFiction isNonFiction
1111 Bestsellers 0 0
2222 Romance 1 0
3333 Biographies 0 1
4444 History 0 1
因此,在 INSERT INTO 运行后,tmp_table 将如下所示:
asin title node
B11111111 Book1 1111
B11111111 Book1 2222
B11111111 Book1 3333
B22222222 Book2 1111
B22222222 Book2 3333
B22222222 Book2 4444
B33333333 Book3 1111
B33333333 Book3 2222
Book1 没有节点 5555 的记录,因为它不在流派表中,我们在 tmp_table 中不需要它。其他所有内容几乎都是数据的反规范化,因为 WHERE 可以识别数据库中数百万本书中的一小部分,这可以更快地使用。
下一步确保如果一本书有 isFiction 节点,则删除该书的所有 isNonFiction 节点。
运行 DELETE 后,tmp_table 中的最终结果为:
asin title node
B11111111 Book1 1111
B11111111 Book1 2222
B22222222 Book2 1111
B22222222 Book2 3333
B22222222 Book2 4444
B33333333 Book3 1111
B33333333 Book3 2222
唯一的区别是 Book1 的节点 3333 已被删除,因为 Book1 位于 isFiction=1 的 2222 节点中,而节点 3333 的 isNonFiction=1。Book2 没有改变,因为它不包含 isFiction 节点。同样,Book3 未更改,因为它不包含 isNonFiction 节点。
在这个阶段,它正在使用这个实现,尽管运行时间从大约 20 多秒增加到大约 40 秒。这并不奇怪,因为 DELETE 有点令人费解。这可能是一个足够体面的解决方案,但如果其他人有一个想法可以让整个事情变得更简单或更快,我会很高兴。
标记...