Как улучшить мои таблицы и запросы для приложений больших данных? - PullRequest
0 голосов
/ 30 августа 2018

Я создал API на Symfony, который ежедневно генерирует более 1 миллиона записей в одну из таблиц MySql. Эта структура таблицы определяется следующим образом:

enter image description here

После нескольких недель использования в таблице уже 35 миллионов (не триллионов) строк. И когда я запрашиваю эту таблицу, время ответа составляет почти 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, который не был разработан для случаев использования больших данных.

Я знаю, что можно улучшить производительность MySQL, используя такие инструменты, как Hadoop, или, например, оптимизируя индексы.

Но будет ли этого достаточно в связи с очень низкими показателями в данный момент?

Я хочу быть уверен, что Symfony - хороший выбор для этого приложения. Я подумываю о переносе API на другую базовую платформу, такую ​​как ASP.NET или Node.JS. Что ты думаешь?

Ответы [ 2 ]

0 голосов
/ 31 августа 2018
  • Узнайте об индексации. Этот конкретный запрос (который кажется странным) нуждается в `INDEX (date_minute, rank).
  • Подсчитайте: не существует диска, способного принять 35 триллионов строк за несколько недель.
  • Ваш AUTO_INCREMENT имеет ограничение в 2 миллиарда. Это не будет поддерживать 35 триллионов строк.
  • Не разбивайте значения даты / времени на несколько столбцов.
  • Не используйте 4-байтовый INT для 1-байтовых величин, таких как "date_minute". Смотри TINYINT UNSIGNED.
  • Используйте числовые типы данных (не LONGTEXT) для числовых значений (объем, рыночная капитализация и т. Д.).
  • Не включайте created и updated, если только вы не собираетесь что-то делать с этими столбцами. (Третьим пакетам, кажется, нравится генерировать их, но тогда не используйте их.)

Я использую типы данных, потому что таблица будет очень большой; Сокращение типов данных, где это возможно, поможет вписаться в ваш ограниченный диск и ускорить запросы.

0 голосов
/ 30 августа 2018

Во-первых, вы не должны относиться к Доктрине как к неотъемлемой части Symfony. Вы можете удалить его и переключиться на другую реализацию ORM, или, возможно, пропустить Doctrine ORM и просто использовать вместо этого DBAL. Кроме того, иногда устранение накладных расходов на ORM или повторение наборов результатов может привести к повышению производительности.

Во-вторых, речь идет не о Symfony или Doctrine, а о том, как вы организуете данные в своем приложении. Вопрос, который вы должны задать, заключается в том, используете ли вы правильный инструмент для работы. Как предлагается в нескольких комментариях, вы можете полностью переключить хранилище (как, например, использовать ElasticSearch в качестве хранилища).

А также вам определенно следует использовать типичные методы оптимизации запросов (например, выполнить запрос EXPLAIN и посмотреть, где узкое место).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...