Mysql 把东西放在一起?有没有什么概念上的权衡
考虑一下,如果一个小的重新设计是你的选择。我从前面的对话中了解到,您在表thing_标记中存储同一事物的多行(甚至300K+)相同标记字符串。这意味着您有一个非规范化的字符串篮,它会降低索引或索引内存的利用率,这两者都会降低性能。将标记字符串放入标记表中,然后创建一个“bridge”/n:n表tag2thing,其中仅包含字段:tagid和thingid。一旦这样做了,将语句拆分是有意义的:1。搜索标签的ID,然后选择2。依靠tag2things和您的things表的连接Mysql 把东西放在一起?有没有什么概念上的权衡,mysql,innodb,query-performance,Mysql,Innodb,Query Performance,考虑一下,如果一个小的重新设计是你的选择。我从前面的对话中了解到,您在表thing_标记中存储同一事物的多行(甚至300K+)相同标记字符串。这意味着您有一个非规范化的字符串篮,它会降低索引或索引内存的利用率,这两者都会降低性能。将标记字符串放入标记表中,然后创建一个“bridge”/n:n表tag2thing,其中仅包含字段:tagid和thingid。一旦这样做了,将语句拆分是有意义的:1。搜索标签的ID,然后选择2。依靠tag2things和您的things表的连接 从你的评论中,我可以得
从你的评论中,我可以得出你有两个选择,都有利弊:
哦,嗨,我在Cloudspace工作(我们写了你链接到的博客文章) 一种方法是更改
things
表,并添加tags\u count
列。然后,无论您在何处创建或销毁thing\u标记
,您都会添加一个更新查询来递增或递减相应的thing
这将允许您使用以下内容选择计数
SELECT * FROM things
WHERE things.datestamp > @start AND things.datestamp < @end
AND EXISTS (
SELECT 1 from thing_tags
WHERE things.id = thing_tags.thing_id
AND thing_tags.tag = @searchTag
)
LIMIT ?
SELECT SUM(tags_count)
FROM things
WHERE things.datestamp > @start AND things.datestamp < @end
哦,嗨,我在Cloudspace工作(我们写了你链接到的博客文章) 一种方法是更改
things
表,并添加tags\u count
列。然后,无论您在何处创建或销毁thing\u标记
,您都会添加一个更新查询来递增或递减相应的thing
这将允许您使用以下内容选择计数
SELECT * FROM things
WHERE things.datestamp > @start AND things.datestamp < @end
AND EXISTS (
SELECT 1 from thing_tags
WHERE things.id = thing_tags.thing_id
AND thing_tags.tag = @searchTag
)
LIMIT ?
SELECT SUM(tags_count)
FROM things
WHERE things.datestamp > @start AND things.datestamp < @end
如果它对任何有类似问题的人都有帮助,我就放弃了——我用一个更大(但仍然合理)的限制进行第二次查询,然后将结果呈现为“100+中的1-10”(或者更大的限制是什么)。这足够满足我的需要了
简单的回答是,在这种数据库中,如果不在其他地方手动维护单独的计数值,就无法获得这种查询的“非常接近”的估计值。如果这对任何有类似问题的人都有帮助,我最终放弃了——我以更大(但仍然合理)的限制进行第二次查询,然后将结果呈现为“100+中的1-10”(或更大的限制)。这足够满足我的需要了
简单的回答是,在这种数据库中,如果不在其他地方手动维护单独的计数值,就无法获得这种查询的“非常接近”估计值。Explain速度非常快,但实际上甚至无法给出最终结果的估计值。它显示了
thing_tags
的行数,但这是我查询的实际正确结果的3倍多;你能发布解释吗?我认为你的内爆不会成功;对于一些常见的标记值,查询将以数十万计。这就是问题的症结所在——我正在从30万条记录中选择第一条,比如说,100条记录,但计算30万条记录需要10秒,而实际结果在10毫秒内返回……你有没有考虑过这样的事情:?-“innodb_buffer_pool_大小70-80%的内存是一个安全的赌注。我将它设置为16GB盒上的12G。”我走这条路线,通常不担心计数300K-可能语句分隔不是真的必要。解释速度非常快,但实际上甚至没有给出最终结果的估计。它显示了thing_tags
的行数,但这是我查询的实际正确结果的3倍多;你能发布解释吗?我认为你的内爆不会成功;对于一些常见的标记值,查询将以数十万计。那是cru
SELECT SUM(tags_count)
FROM things
WHERE things.datestamp > @start AND things.datestamp < @end
SELECT count(thing_tags.id)
FROM thing_tags
INNER JOIN things
ON thing_tags.thing_id = things.id
WHERE things.datestamp > @start
AND things.datestamp < @end
AND thing_tags.tag = @searchTag