我在Symfony上创建了一个API,该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。你觉得呢?
答案 0 :(得分:3)
首先,您不应该将教义视为Symfony不可分割的一部分。您可以随意删除它并切换到其他ORM实施,也可以跳过Doctrine ORM,而只使用DBAL。另外,有时消除ORM或iterating the result sets的开销可能会为您带来性能提升。
第二,这与Symfony或Doctrine无关,实际上与在应用程序中组织数据的方式有关。您应该问的问题是您是否使用正确的工具来完成工作。如几条评论中所建议,您可以完全切换存储(例如,使用ElasticSearch作为存储)。
当然,您也绝对应该使用典型的查询优化技术(例如,运行EXPLAIN
查询并查看瓶颈在哪里)。
答案 1 :(得分:1)
AUTO_INCREMENT
的上限为20亿。那将不支持35万亿行。INT
。参见TINYINT UNSIGNED
。LONGTEXT
)用于数字值(交易量,市值等)。created
和updated
。 (第三个软件包似乎喜欢生成它们,但是不要使用它们。)我要处理数据类型,因为表会变得很大;尽可能缩小数据类型将有助于使其适合您的有限磁盘,并有助于加快查询速度。