Какая разница в использовании find_by_sql и нашего обычного метода запроса рельсов? - PullRequest
2 голосов
/ 01 сентября 2011

У меня есть небольшое сомнение относительно времени выполнения запроса MySQL в моем приложении rails.

Я написал запрос типа

  @claims = Claim.joins('left join drugs on claims.ndc = drugs.ndcupchri left join pharmacies on claims.nabp = pharmacies.nabp').select('claims.*, drugs.*, pharmacies.* ').where('claims.member_id = '218').group(:ndc)

, и я написал тот же запрос, используя find_by_sql

   @sql = "SELECT claims.*, drugs.*, pharmacies.* FROM `claims` 
          left join drugs on claims.ndc = drugs.ndcupchri 
          left join pharmacies on claims.nabp = pharmacies.nabp 
          WHERE (claims.member_id = '218') GROUP BY ndc "

  @claims = Claim.find_by_sql(@sql)

Иногда я вижу, что при использовании find_by_sql время выполнения запроса довольно быстрое по сравнению с другим.Это правильно.

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

В настоящее время я использую Rails 3.0.7

Ответы [ 2 ]

2 голосов
/ 01 сентября 2011

Первый запрос использует Arel.Это обеспечивает цепочечность и объем.Таким образом, если вы хотите отфильтровать больше данных, вы можете сделать что-то вроде:

@claims.where(:id => 5)

Вышеописанное невозможно с find_by_sql.Также Arel выполняет оптимизацию SQL-запросов, сформированных с использованием методов Arel.Вы можете искать другие преимущества Arel в google. В rails 3.1 будет кэширование результатов запросов к базе данных (поправьте меня, если я ошибаюсь)

Если вы хорошо разбираетесь в sql, то find_by_sql всегда будет более оптимизированнымкак он выполняет запросы непосредственно в базе данных.Но тогда мы всегда хотим баланса в производительности и производительности.

0 голосов
/ 01 сентября 2011

в вашем случае предложение joins является чрезмерным, так как вы не налагаете никаких условий WHERE на таблицы соединений, только на таблицу заявок, а при вызове Claim.find_by_sql будут заполнены только объекты заявки. Таким образом, ваш запрос сводится к

Claim.where(:member_id => 218)

Это будет быстрее, чем оба ваших запроса, поскольку объединения не выполняются.

Как правило, через find_by_sql следует выполнять только некоторые конкретные запросы. Rails Интерфейс Arel достаточно гибок для реализации большинства часто используемых запросов, и намного проще отлаживать эти огромные операторы SQL.

...