mysql - 如何改进大数据应用程序的表和查询?
问题描述
我在 Symfony 上创建了一个 API,它每天在其中一个 MySql 表中生成超过 100 万个条目。这个表结构是这样定义的:
经过几周的使用,该表已经有 3500 万(不是万亿)行。当我查询这张表时,对于这样一个简单的查询,响应时间几乎是 20 秒:
public function findAllCryptosByRank($date_minute)
{
$query = $this->_em->createQueryBuilder()
->select("cm")
->from("APIBundle:CoinmarketcapSnapshot", "cm")
->where("cm.date_minute = :date_minute")
->orderBy("cm.rank", "ASC")
->setMaxResults(10)
->setParameters(array(
'date_minute' => $date_minute,
));
$finalQuery = $query->getQuery();
return $finalQuery->getArrayResult();
}
做更复杂的事情时,情况会更糟;查询需要一分钟以上。例如对于这样的事情:
public function findAllCryptosByRank($date_minute,$date_hour,$date_day,$date_month,$date_year)
{
$query = $this->_em->createQueryBuilder()
->select("cm", "c.logo", "c.title")
->from("APIBundle:CoinmarketcapSnapshot", "cm")
->where("cm.date_minute = :date_minute")
->andWhere("cm.date_hour = :date_hour")
->andWhere("cm.date_day = :date_day")
->andWhere("cm.date_month = :date_month")
->andWhere("cm.date_year = :date_year")
->leftJoin(
'APIBundle:Cryptocurrency',
'c',
\Doctrine\ORM\Query\Expr\Join::WITH,
'cm.cryptocurrency__id = c. coinmarketcap_id'
)
->orderBy("cm.rank", "ASC")
->setMaxResults(10)
->setParameters(array('date_minute'=>$date_minute,'date_hour'=>$date_hour,'date_day'=>$date_day,'date_month'=>$date_month,'date_year'=>$date_year))
;
$finalQuery = $query->getQuery();
return $finalQuery->getArrayResult();
}
那么,我能做些什么来极大地提高这些性能呢?我读到了 Doctrine,它不是为大数据用例设计的。
我知道可以通过使用 Hadoop 等工具或优化索引来提高 MySQL 性能。
但这对于目前非常低的性能来说就足够了吗?
我想确定 Symfony 是这个应用程序的不错选择。我正在考虑将 API 迁移到另一个后端框架,例如 ASP.NET 或 Node.JS。你怎么看?
解决方案
首先,您不应该将 Doctrine 视为 Symfony 不可分割的一部分。您可以随意删除它并切换到不同的 ORM 实现,或者可以跳过 Doctrine ORM 而只使用 DBAL。此外,有时消除 ORM 的开销或迭代结果集可能会给您带来性能升级。
其次,这与 Symfony 或 Doctrine 无关,这实际上与您在应用程序中组织数据的方式有关。您应该问的问题是您是否为工作使用了正确的工具。正如一些评论中所建议的,您可以完全切换存储(例如,使用 ElasticSearch 作为存储)。
而且您绝对应该使用典型的查询优化技术(例如,运行EXPLAIN
查询并查看瓶颈在哪里)。
推荐阅读
- python - 如何配置 IPython 以与普通 Python REPL 相同的方式执行单元块?
- c - Essential C 中的 Swap() func 无法编译
- java - Spring Boot - application.properties 中的程序参数
- webcam - 如何使用分段输出文件在 DirectShow 中预览和捕获?
- networking - 如何确定 sctp 包中的块数?
- asp.net-mvc - 在 DataModel 中添加新表时 LINQ to Entities 查询
- maven - cli 的 GAE 成功,Cloud Build 的失败。错误:未找到
- c# - Xamarin Intent 空指针
- spring - Spring Boot WebClient.Builder bean 在传统 servlet 多线程应用程序中的使用
- python - 通过设置固定长度将列表转换为字典