我有一个 MySQL 数据库,其中包含一些(准确地说是五个)巨大的表。它本质上是一个基于星型拓扑结构的数据仓库。表大小范围从 700GB(事实表)到 1GB,整个数据库高达 1 TB。现在我被赋予了对这些表运行分析的任务,其中甚至可能包括连接。 对该数据库的一个简单分析查询可以是“找到每个州的吸烟者数量并按降序显示”这个需求可以转换为一个简单的查询,如
select state, count(smokingStatus) as smokers
from abc
having smokingstatus='current smoker'
group by state....
此查询(以及许多其他相同性质的查询)在此数据库上执行需要花费大量时间,所用时间约为数十小时。
该数据库还大量用于插入,这意味着每隔几分钟就会添加数千行。
在这种情况下,我该如何解决这个查询问题? 我看过 Cassandra,它似乎很容易实现,但我不确定它是否会像在数据库上运行分析查询一样容易,尤其是当我必须使用“where 子句和按构造分组”时
还查看了 Hadoop,但我不确定如何实现 RDBMS 类型的查询。我不太确定我是否想立即投资购买至少三台机器用于名称节点、动物园管理员和数据节点!!最重要的是,我们公司更喜欢基于 Windows 的解决方案。
我还考虑过在更简单的汇总表中预先计算所有数据,但这限制了我运行不同类型查询的能力。
还有什么我可以实现的其他想法吗?
编辑
以下是mysql环境搭建
1) 主从设置 2)插入/更新的主人 3) 用于读取和运行存储过程的slave 4)所有表都是innodb,每个表都有文件 5) 字符串和 int 列的索引。
预计算值是一种选择,但由于对这种临时聚合值的要求不断变化。
最佳答案
从试图让 MySQL 更好地工作而不是提出一个全新的架构系统的角度来看:
首先,验证到底发生了什么。解释导致问题的查询,而不是猜测发生了什么。
话虽如此,由于我没有查询计划,所以我将猜测发生了什么。我猜 (a) 你的索引没有被正确使用,你得到了一堆可以避免的表扫描,(b) 你的数据库服务器针对 OLTP 而不是分析查询进行了调整,(c) 在读取时写入数据导致事情大大减慢,(d) 使用字符串很糟糕,(e) 你有一些低效的查询和可怕的连接(每个人都有一些)。
为了改进,我会调查以下内容(大致按此顺序):
检查查询计划,确保正确使用现有索引 - 查看表扫描,确保查询确实有意义。
将分析查询从 OLTP 系统中移出 - 快速插入和短查询所需的调优与可能读取大表的大部分查询的调优大不相同。这可能意味着拥有另一个具有不同配置(以及可能的表类型 - 我不确定 MySQL 目前的最新技术水平)的仅分析从站。
将字符串移出事实表 - 而不是让吸烟状态列的字符串值为(比如)'current smoker'、'recently quit'、'quit 1+ years'、'never smoked' ,将这些值推送到另一个表,并在事实表中包含整数键(这也有助于索引的大小)。
在查询运行时停止更新表 - 如果索引在查询运行时移动,我看不到好事发生。 (幸运的是)我已经有很长时间不关心 MySQL 复制了,所以我不记得你是否可以在没有太多戏剧性的情况下批量写入分析查询从属。
如果您在没有解决性能问题的情况下走到这一步,那么是时候考虑离开 MySQL 了。我会先看看 Infobright——它是开源的/$$ & 基于 MySQL,所以它可能是最容易放入现有系统的(确保数据进入 InfoBright DB,然后将你的分析查询指向 Infobright服务器,保持系统的其余部分不变,工作完成),或者如果 Vertica 曾经发布其社区版。 Hadoop+Hive 有很多事件部件 - 它非常酷(并且在简历上很棒),但如果它只用于系统的分析部分,它可能比其他选项需要更多的关注和支持。
关于mysql - 在庞大的 MySQL 数据库上运行分析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9777284/