Dplyr — использование индексов для оптимизации запросов

На моей работе мы работаем с базами данных (преимущественно MySQL 5.7.2, это то, что я не могу изменить). Обычно задача заключается в написании сложных запросов к наборам данных, состоящим из миллионов строк. Это делается с помощью потока запросов MySQL, строящихся друг над другом (каждый из которых является временной таблицей, со следующей временной таблицей, построенной на предыдущих и т. д.). Поскольку количество строк исчисляется миллионами, включая соединения с несколькими столбцами, для этих временных таблиц выполняется индексация с использованием операторов alter table.

Теперь, когда я пытаюсь понять, как использовать dplyr и изучить возможности каналов, мне кажется, что это прекрасное решение для тех проблем, которые мы решаем; т. е. запросы строятся друг над другом. Поэтому я написал простые сценарии, использующие возможности dplyr. Я отправляю все запросы обратно в MySQL, чтобы оценить конечный результат (конечный результат — всего несколько сотен строк). Таким образом, вся обработка будет выполняться на удаленном сервере MySQL без необходимости загрузки миллионов строк в локальный экземпляр R, и только набор результатов будет извлечен локальным экземпляром R.

Однако я столкнулся с узким местом, где требуется индексация; и это абсолютно необходимо из-за проблем с производительностью. Как я вижу, я могу использовать функцию copy_to в dplyr, которая дает мне возможность добавлять индексы; тут меня смущают две вещи:

  1. Мне нужно создать новую таблицу на удаленном сервере MySQL для хранения результата copy_to (в большинстве сценариев нам разрешены только временные таблицы).

  2. Даже если мне каким-то образом удастся написать постоянную таблицу, функция copy_to не позволит мне определить собственное имя индекса, как в MySQL; в то время как имя по умолчанию, которое он придумал, слишком длинное для MySQL (выдает ошибки по длине имени индекса).

Мы будем очень признательны за любые советы по использованию индексов с dplyr. В идеале я хочу что-то вроде того, что показано в смелый ниже:

Tbl1 %>% filter(...) %>% mutate(...) %>% left_join(Tbl2, by("col1" = "col1", "col2" = "col2") %>% add_index(col_from_tbl1, col_from_tbl2) %> % другие операции

Кстати, я вижу, что решение для длинного имени индекса состоит в том, чтобы копировать_в новую таблицу; затем используйте DBI::dbSendQuery, чтобы добавить индекс с именем по моему выбору; это работает. Однако потребность в индексации возникает очень часто. Из-за этого элегантность использования каналов исчезает, так как мне нужно остановиться в середине цепочки каналов, скопировать_в новую таблицу, а затем добавить индекс с помощью dbSendQuery; а затем снова начать использовать трубы. Весь смысл иметь хорошо читаемый код исчезает.

Paste и paste0 могут подойти вам, а также есть sprintf. Я вижу, что, поскольку вы используете функцию Tidyverse в dplyr, вы можете обнаружить, что glue лучше.
bob1 01.03.2019 16:14

Конвейерная обработка и использование множества временных таблиц в последовательности — это способ значительно замедлить весь процесс. Попробуйте написать один оператор SQL. Как и в большинстве сторонних пакетов, базовый SQL является ключом к производительности; пакет может действительно мешать.

Rick James 08.03.2019 00:22

Спасибо @RickJames. Это имеет смысл. Тем не менее, я по-прежнему вижу преимущества этого пути: 1) быстрое построение запроса 2) легко понять 3) более надежный в случаях, когда нам нужно использовать запрос для нескольких анализов, а затем отбросить (предварительное время, необходимое для планирование более сложного отдельного оператора сохраняется; в любом случае, для посредственного автора SQL-запросов).

Imtiaz 11.03.2019 12:04

Что ж, изучите запросы и временные таблицы, которые dplyr строит для вас. Вскоре вы освоитесь и будете готовы бросить dplyr. (Я трачу слишком много времени, помогая программистам на этом форуме устранять недостатки сторонних пакетов, которые «помогают» им избежать изучения SQL.)

Rick James 11.03.2019 15:58
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
2
4
265
0

Другие вопросы по теме