Mysql 如何提高ActiveRecord和数据库的性能问题
我正在使用Rails3.2.13、Mysql和Sql来过滤记录。搜索是完美的。但返回结果需要更多的时间(超过一分钟) 我不能在这里使用即时加载,因为使用了带连接的原始sql查询,并且我不能使用缓存,因为我们的记录将根据过滤器频繁更改。仅供参考,我已经在表中使用了索引 任何解决方案都将不胜感激。提前谢谢 我的控制器:Mysql 如何提高ActiveRecord和数据库的性能问题,mysql,sql,ruby-on-rails,ruby-on-rails-3.2,Mysql,Sql,Ruby On Rails,Ruby On Rails 3.2,我正在使用Rails3.2.13、Mysql和Sql来过滤记录。搜索是完美的。但返回结果需要更多的时间(超过一分钟) 我不能在这里使用即时加载,因为使用了带连接的原始sql查询,并且我不能使用缓存,因为我们的记录将根据过滤器频繁更改。仅供参考,我已经在表中使用了索引 任何解决方案都将不胜感激。提前谢谢 我的控制器: class ProjectReportsController < ApplicationController def index @results = Projec
class ProjectReportsController < ApplicationController
def index
@results = ProjectCustomValueSearch.new(params[:teams], params[:contract_types], params[:retainer_ends], params[:retainer_ends_date], params[:status]).search
end
end
class ProjectReportsController
我的模型:
class ProjectCustomValueSearch
attr_reader :teams, :contract_types, :retainer_ends, :retainer_ends_date, :status
def initialize(teams, contract_types, retainer_ends, retainer_ends_date, status)
@teams = teams
@contract_types = contract_types
@retainer_ends = retainer_ends
@retainer_ends_date = retainer_ends_date
@status = status
end
def search
#add status filter condition
status_query = (@status=='Both' || @status.blank?) ? " p.status = 1 OR p.status = 5" : " p.status = #{ActiveRecord::Base.sanitize(@status)}"
other_conditions = ''
#add team filter condition
if (@teams!='DM' && @teams!='Web')
other_conditions += " AND cv_team.value #{all_none_condition(@teams, 'cv_team.value')}"
elsif (@teams=="DM" || @teams=="Web")
other_conditions += " AND #{dm_or_web_condition(@teams)}"
end
#add cv_contract_type filter condition
other_conditions += " AND cv_contract_type.value #{all_none_condition(@contract_types, 'cv_contract_type.value')}"
#add cv_retainer_end value and cv_retainer_end date filter conditions
other_conditions += " AND cv_retainer_end.value #{before_after_condition(@retainer_ends_date, @retainer_ends)}" if @retainer_ends_date.present?
#Sql query is something like this:
sql = <<-sql
select p.id, p.name as project_name,
u_web_pm.firstname as web_pm_firstname,
u_web_pm.lastname as web_pm_lastname,
concat(u_marketing_pm.firstname, ' ', u_marketing_pm.lastname) as marketing_pm_value,
u_client_contact.firstname as client_contact_firstname,
u_client_contact.lastname as client_contact_lastname,
FORMAT(Round(cv_monthly_retainer.value, 0), 0) as monthly_retainer_value,
FORMAT(Round(cv_project_budget.value, 0), 0) as project_budget_value,
cv_rates.value as rates_value,
cv_retainer_start.value as retainer_start_value,
cv_retainer_end.value as retainer_end_value,
cv_contract_type.value as contract_type_value,
cv_team.value as team_value,
cv_discount.value as discount_value,
cv_account_rep.value as account_rep_value,
FORMAT(Round(cv_project_budget.value / 150, 0), 0) as budget_project,
FORMAT(Round(cv_monthly_retainer.value / 150, 0), 0) as budget_retainer,
FORMAT(Round(sum(time_entry.hours), 0), 0) as total_hours
from projects p
#Web PM
left join custom_values as cv_web_pm on p.id = cv_web_pm.customized_id and cv_web_pm.custom_field_id=4
left join users as u_web_pm on cv_web_pm.value = u_web_pm.id
#Marketing PM
left join custom_values as cv_marketing_pm on p.id = cv_marketing_pm.customized_id and cv_marketing_pm.custom_field_id=5
left join users as u_marketing_pm on cv_marketing_pm.value = u_marketing_pm.id
#Client Contact
left join custom_values as cv_client_contact on p.id = cv_client_contact.customized_id and cv_client_contact.custom_field_id=6
left join users as u_client_contact on cv_client_contact.value = u_client_contact.id
#Monthly Retainer
left join custom_values as cv_monthly_retainer on p.id = cv_monthly_retainer.customized_id and cv_monthly_retainer.custom_field_id=7
#Project Budget
left join custom_values as cv_project_budget on p.id = cv_project_budget.customized_id and cv_project_budget.custom_field_id=8
#Rates
left join custom_values as cv_rates on p.id = cv_rates.customized_id and cv_rates.custom_field_id=9
#Retainer Start
left join custom_values as cv_retainer_start on p.id = cv_retainer_start.customized_id and cv_retainer_start.custom_field_id=10
#Retainer End
left join custom_values as cv_retainer_end on p.id = cv_retainer_end.customized_id and cv_retainer_end.custom_field_id=11
#Contract Type
left join custom_values as cv_contract_type on p.id = cv_contract_type.customized_id and cv_contract_type.custom_field_id=12
#Team
left join custom_values as cv_team on p.id = cv_team.customized_id and cv_team.custom_field_id=13
#additional filters
where #{status_query}
#{other_conditions}
Group BY p.id
order by p.name ASC
sql
ActiveRecord::Base.connection.execute(sql)
end
private
def all_none_condition(str, field='')
case str
when 'All'
return " = '' or #{field} <> '' "
when 'Any'
return " <> '' "
when 'None'
return " = '' "
else
return " = #{ActiveRecord::Base.sanitize(str)}"
end
end
def dm_or_web_condition(str)
case str
when 'DM'
return " (cv_team.value='DM 1' OR cv_team.value='DM 2') "
when 'Web'
return " (cv_team.value='Web 1' OR cv_team.value='Web 2') "
end
end
def before_after_condition(date, condition)
case condition
when 'Before'
return " < #{ActiveRecord::Base.sanitize(date)} and cv_retainer_end.value <> ''"
when 'After'
return " > #{ActiveRecord::Base.sanitize(date)} and cv_retainer_end.value <> ''"
end
end
end
class ProjectCustomValueSearch
属性读取器:团队,:合同类型,:聘用人员结束,:聘用人员结束日期,:状态
def初始化(团队、合同类型、聘用结束、聘用结束日期、状态)
@团队=团队
@合同类型=合同类型
@夹持器端部=夹持器端部
@聘用结束日期=聘用结束日期
@状态=状态
结束
def搜索
#添加状态筛选条件
status|u query=(@status=='Both'| |@status.blank?)?“p.status=1或p.status=5”:“p.status={ActiveRecord::Base.sanitize(@status)}”
其他条件=“”
#添加团队筛选条件
如果(@teams!='DM'&&&teams!='Web')
其他_条件+=“和cv_team.value{all_none_条件(@teams,'cv_team.value'))
elsif(@teams==“DM”| |@teams==“Web”)
其他_条件+=“和#{dm_或_web_条件(@teams)}”
结束
#添加cv_合同_类型筛选条件
其他条件+=“和cv_合同类型.value{all_none_条件(@contract_types,'cv_合同类型.value'))
#添加cv_保持器_结束值和cv_保持器_结束日期过滤条件
其他条件+=“和cv_reserver_end.value#{在条件之后(@reserver_ends_date,@reserver_ends)}”如果@reserver_ends_date.present?
#Sql查询如下所示:
sql=