MySQL UNION ALL 多重使用优化
Posted
技术标签:
【中文标题】MySQL UNION ALL 多重使用优化【英文标题】:MySQL UNION ALL Multiple usage optimization 【发布时间】:2021-08-10 05:32:07 【问题描述】:我在 mysql 查询优化方面遇到问题。 情况如下。 SQL 表中有超过 200000 行包含多列。 我正在为这些数据在前端制作过滤器选项。 例如,两列“Year”和“Make”。 并且在Year栏中有许多值,如“2021”、2022、2019、2010,而在Make中则有“Ford”、“Chevrolet”等。 示例链接: https://www.autobidmaster.com/en/carfinder-online-auto-auctions/?make=Chevrolet
这些值在每一列中不是唯一的。和 我将根据这两列的唯一值制作过滤器选项(唯一值:每列中的计数)。 我想我可以在每个查询中使用按唯一值分组的数据,并在单个查询中使用 UNION ALL 合并它们。 例如:对于两列 Year 和 Make
$sql1 = "
(SELECT 'Make' as filter_option_name ,Make as filter_options_key_name, COUNT(*) as filter_option_count
FROM dbcopart.wprdb_copartdata ". $where_str ."
GROUP BY filter_options_key_name
ORDER BY filter_options_key_name)
UNION ALL
(SELECT 'Year' as filter_option_name ,Year as filter_options_key_name, COUNT(*) as filter_option_count
FROM dbcopart.wprdb_copartdata ". $where_str ."
GROUP BY filter_options_key_name
ORDER BY filter_options_key_name) "
有两列,没关系。工作正常。 但还有另一列:超过 20 列用作过滤器选项。 超过 200000 行的 20 次 UNION ALL 很慢。 如何改进我的 SQL 查询? 我认为应该有另一种有效的方法来代替我愚蠢的“多个 UNION ALL”。 感谢您的关注。
【问题讨论】:
问题:随着人们为“年份”、“品牌”和“颜色”等添加过滤器,预计计数会发生变化吗?如果数据库中有 50,000 辆红色汽车,但我选择兰博基尼作为制造商,那么再显示 50,000 辆就没有意义了。在选择每个过滤器选项以进一步细化匹配数量后,您的网站是否会返回数据库? 您好抱歉迟到了,是的,应该再次完善。这就是我感到压力的原因。因为如果我们不需要细化匹配计数,我可以将所有过滤器选项保存在另一个表中作为静态并稍后使用。 【参考方案1】:您的UNION ALL
可能是一次收集所有 20 组计数的最佳选择。但是考虑每小时运行一次并将其存储到另一个表中 - 然后使用从该表中获取。 (数据会有点陈旧,但对于用例来说可能已经足够了。)
是的,一旦他们选择了“兰博基尼”,您将不得不返回表格以获取所有计数的修订值(减去 make
)。如果有一个索引以 make
开头,那么第二个大 UNION 将比第一个更快。
两层可能值得缓存;超出此范围将占用大量空间,而收益却微乎其微。
考虑将整个数据集保存在内存中,并使用应用代码进行必要的计数;它可能会比使用 SQL 更快。 (但代码要多得多。)
【讨论】:
感谢您的回答,您能解释一下如何重新制作以make开头的索引吗?关于内存使用,实际上我每 15 分钟将 CSV 中的数据集放入数据库中,基于 cron 作业。我可能使用 CSV 本身而不是数据库? @JansenLee - 示例:ALTER TABLE wprdb_copartdata ADD INDEX(make, year)
。 CSV 没有有用的索引;使用数据库可能会更好。开始一个关于 15 分钟 cron 作业的新问题;出现多个危险信号。以上是关于MySQL UNION ALL 多重使用优化的主要内容,如果未能解决你的问题,请参考以下文章