如何改进我的大数据应用程序的表和查询?

jdzmm42g  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(288)

我在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();
}

那么,我该怎么做才能极大地提高这些性能呢?我读过一篇关于条令的文章,它不是为大数据用例设计的。
我知道使用hadoop之类的工具,或者优化索引,可以提高mysql的性能。
但对于目前的低水平表现,这就足够了吗?
我想确定symfony是这个应用程序的好选择。我正在考虑将api迁移到另一个后端框架,如asp.net或node.js。你怎么认为?

pu3pd22g

pu3pd22g1#

首先,你不应该把教义当作symfony不可分割的一部分。您可以随意删除它并切换到不同的orm实现,也可以跳过orm而改用dbal。此外,有时消除orm的开销或迭代结果集可能会提高性能。
第二,这不是关于symfony或条令,而是关于在应用程序中组织数据的方式。你应该问的问题是你是否使用了合适的工具。正如一些评论所建议的,您可以完全切换存储(例如,使用elasticsearch作为存储)。
而且您还应该明确地使用典型的查询优化技术(例如,运行 EXPLAIN 查询并查看瓶颈在哪里)。

dm7nw8vv

dm7nw8vv2#

了解索引。这个特殊的查询(看起来很奇怪)需要索引(date\u minute,rank)。
算算一下:没有一个磁盘可以在几周内接受35万亿行。
你的 AUTO_INCREMENT 上限是20亿。这将不支持35万亿行。
不要将日期/时间值拆分为多个列。
不要使用4字节 INT 对于1字节的量,例如“date\u minute”。看到了吗 TINYINT UNSIGNED .
使用数字数据类型(不是 LONGTEXT )对于数值(数量、市值等)。
不包括 created 以及 updated 除非你想对这些列做点什么(第三个软件包似乎喜欢生成它们,但不要使用它们。)
我反复强调数据类型,因为表将变得非常大;尽可能缩小数据类型将有助于它适应您有限的磁盘,并有助于加快查询速度。

相关问题