Skip to content

Commit 237ce43

Browse files
committed
[Rails5] Performance optimizations.
These changes make the full ActiveRecord test suite run about 100s faster from ~580s to ~480s. * Use the `schema_cache.columns` for the `#primary_keys` method. * Ensure that `exec_query` uses the proper arity/arg names. Namely `:prepare` opt. * Ensure all view checks/methods used in `#columns` only. * Removed view table name detection in `with_identity_insert_enabled` method for fixtures. * Removed `#select` abstract adapter override since it was the same.
1 parent ae0296c commit 237ce43

File tree

4 files changed

+11
-25
lines changed

4 files changed

+11
-25
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#### Removed
1717

1818
* ODBC connection mode. Not been maintained since Rails 4.0.
19+
* View table name detection in `with_identity_insert_enabled` method for fixtures. Perf hit.
1920

2021
#### Fixed
2122

lib/active_record/connection_adapters/sqlserver/database_statements.rb

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ def execute(sql, name = nil)
1515
end
1616
end
1717

18-
def exec_query(sql, name = 'SQL', binds = [], sqlserver_options = {})
19-
sp_executesql(sql, name, binds)
18+
def exec_query(sql, name = 'SQL', binds = [], prepare: false)
19+
sp_executesql(sql, name, binds, prepare: prepare)
2020
end
2121

2222
def exec_insert(sql, name, binds, pk = nil, _sequence_name = nil)
@@ -125,7 +125,7 @@ def execute_procedure(proc_name, *variables)
125125
end
126126

127127
def with_identity_insert_enabled(table_name)
128-
table_name = quote_table_name(table_name_or_views_table_name(table_name))
128+
table_name = quote_table_name(table_name)
129129
set_identity_insert(table_name, true)
130130
yield
131131
ensure
@@ -197,10 +197,6 @@ def newsequentialid_function
197197

198198
protected
199199

200-
def select(sql, name = nil, binds = [])
201-
exec_query(sql, name, binds)
202-
end
203-
204200
def sql_for_insert(sql, pk, id_value, sequence_name, binds)
205201
if pk.nil?
206202
table_name = query_requires_identity_insert?(sql)
@@ -231,8 +227,10 @@ def do_execute(sql, name = 'SQL')
231227

232228
def sp_executesql(sql, name, binds, options = {})
233229
options[:ar_result] = true if options[:fetch] != :rows
234-
types, params = sp_executesql_types_and_parameters(binds)
235-
sql = sp_executesql_sql(sql, types, params, name)
230+
unless without_prepared_statement?(binds)
231+
types, params = sp_executesql_types_and_parameters(binds)
232+
sql = sp_executesql_sql(sql, types, params, name)
233+
end
236234
raw_select sql, name, binds, options
237235
end
238236

lib/active_record/connection_adapters/sqlserver/schema_statements.rb

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def new_column(name, default, sql_type_metadata, null, table_name, default_funct
8080
end
8181

8282
def primary_keys(table_name)
83-
primaries = columns(table_name).select(&:is_primary?).map(&:name)
83+
primaries = schema_cache.columns(table_name).select(&:is_primary?).map(&:name)
8484
primaries.present? ? primaries : identity_columns(table_name).map(&:name)
8585
end
8686

@@ -254,7 +254,7 @@ def column_definitions(table_name)
254254
end
255255
database = identifier.fully_qualified_database_quoted
256256
view_exists = view_exists?(table_name)
257-
view_tblnm = table_name_or_views_table_name(table_name) if view_exists
257+
view_tblnm = view_table_name(table_name) if view_exists
258258
sql = %{
259259
SELECT DISTINCT
260260
#{lowercase_schema_reflection_sql('columns.TABLE_NAME')} AS table_name,
@@ -307,7 +307,7 @@ def column_definitions(table_name)
307307
nv128 = SQLServer::Type::UnicodeVarchar.new limit: 128
308308
binds << Relation::QueryAttribute.new('TABLE_NAME', identifier.object, nv128)
309309
binds << Relation::QueryAttribute.new('TABLE_SCHEMA', identifier.schema, nv128) unless identifier.schema.blank?
310-
results = sp_executesql(sql, 'SCHEMA', binds)
310+
results = sp_executesql(sql, 'SCHEMA', binds, prepare: true)
311311
results.map do |ci|
312312
ci = ci.symbolize_keys
313313
ci[:_type] = ci[:type]
@@ -446,10 +446,6 @@ def view_information(table_name)
446446
view_info
447447
end
448448

449-
def table_name_or_views_table_name(table_name)
450-
view_exists?(table_name) ? view_table_name(table_name) : table_name
451-
end
452-
453449
def views_real_column_name(table_name, column_name)
454450
view_definition = view_information(table_name)[:VIEW_DEFINITION]
455451
return column_name unless view_definition

test/cases/adapter_test_sqlserver.rb

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -396,15 +396,6 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
396396
assert SSTestStringDefaultsView.connection.data_source_exists?(SSTestStringDefaultsView.table_name)
397397
end
398398

399-
# Doing identity inserts
400-
401-
it 'be able to do an identity insert' do
402-
customer = SSTestCustomersView.new
403-
customer.id = 420
404-
customer.save!
405-
assert SSTestCustomersView.find(420)
406-
end
407-
408399
# That have more than 4000 chars for their defintion
409400

410401
it 'cope with null returned for the defintion' do

0 commit comments

Comments
 (0)