首页 > 解决方案 > 如何改进大数据应用程序的表和查询?

问题描述

我在 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。你怎么看?

标签: mysqlsymfonydoctrine-ormbigdata

解决方案


首先,您不应该将 Doctrine 视为 Symfony 不可分割的一部分。您可以随意删除它并切换到不同的 ORM 实现,或者可以跳过 Doctrine ORM 而只使用 DBAL。此外,有时消除 ORM 的开销或迭代结果集可能会给您带来性能升级。

其次,这与 Symfony 或 Doctrine 无关,这实际上与您在应用程序中组织数据的方式有关。您应该问的问题是您是否为工作使用了正确的工具。正如一些评论中所建议的,您可以完全切换存储(例如,使用 ElasticSearch 作为存储)。

而且您绝对应该使用典型的查询优化技术(例如,运行EXPLAIN查询并查看瓶颈在哪里)。


推荐阅读