2016-06-17 2 views
0

У меня есть следующий код:Sequel запрос вызывает скрипт зависает и вызывает компьютер, чтобы замедлить

team_articles = user.npt_teams.to_a.inject({}) {|arts,team| 
    arts.merge({ team.name => 
    NptArticle.join(:npt_authors).join(:users).join(:npt_teams).where(:npt_teams__id => team.id).to_a.uniq}) 
    } 

Это вызывает мой терминал перестает отвечать на запросы и мой Macbook, чтобы замедлить.

В mysqlworkbench он мгновенно получает ответ.

Было предложено создать более легкую версию объекта NptArticle, но я не совсем уверен, как создать версию, которая тянет меньше столбцов, поэтому любое предложение исправить эту проблему было бы здорово.

Это the table.

Сгенерированный SQL является:

SELECT * FROM `npt_articles` INNER JOIN `npt_authors` INNER JOIN `users` INNER JOIN `npt_teams` WHERE (`npt_teams`.`id` = 1) 

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

Results от:

EXPLAIN SELECT * FROM npt_articles INNER JOIN npt_authors INNER JOIN users INNER JOIN npt_teams WHERE (npt_teams.id = 1); 
+0

Не могли бы вы включить описание таблицы и любые индексы, которые вы создали на них? –

+0

Вам действительно нужно срочно обновить этот Ruby. Какой запрос он генерирует? Обычно здесь используется метод '.to_sql'. Использование 'merge' здесь совершенно неуместно, вы генерируете N хэшей в этом процессе. Используйте 'arts [team.name] = ...' и у вас 'arts' как последняя вещь в вашем блоке. – tadman

+0

Можете ли вы опубликовать результат EXPLAIN SELECT * FROM npt_articles INNER JOIN npt_authors INNER JOIN пользователей INNER JOIN npt_teams WHERE (npt_teams.id = 1) – Jaydee

ответ

1

Так что для npt_team.id =1 вы выполняете перекрестное соединение для всех:

npt_articles 
npt_authors 
users 

Если число статей, авторов и пользователей даже умеренные вы получите огромный количество результатов, поскольку объединения не ограничены. Обычно вы должны использовать что-то вроде:

INNER JOIN `npt_authors` ON (npt_articles.ID=npt_authors.articleID) 

(это зависит от того, как относится ваша база данных).

Кроме того, вам понадобятся индексы на полях, которые связывают таблицы друг с другом, что также ускорит процесс.

Посмотрите на столбец строк EXPLAIN SELECT. Это то, сколько строк обрабатывается для каждой части соединения. Чтобы получить оценку общего количества обработанных строк, умножьте эти числа вместе. 1 x 657 x 269723 x 956188 = rather a lot.

Я не Ruby wiz, поэтому, возможно, кто-то еще может опубликовать, как вы это делаете.

+0

святой молибденовые, что это много, я предполагаю, что это не удивительно, это медленно. – Thermatix

+0

Это происходит потому, что база данных не знает, как связывать различные таблицы вместе, поэтому в настоящее время она объединяет все со всем остальным. – Jaydee

+0

@Thermatix https://www.sitepoint.com/understanding-sql-joins-mysql-database/ – Jaydee

Смежные вопросы