Rails : Rake DB : Oracle에서 매우 * 매우 * 매우 *
-
09-09-2019 - |
문제
나는와 함께 레일을 사용하고 있습니다 oracleenhanced
레거시 애플리케이션을위한 새 인터페이스를 작성하는 어댑터.
데이터베이스 마이그레이션은 성공적으로 작동하지만 레이크가 끝나기까지 엄청나게 오랜 시간이 걸립니다. 데이터베이스 변경은 꽤 빨리 발생하지만 (1-2 초) db/schema.db
덤프를 완료하는 데 1 시간 이상이 걸립니다. (아래 마이그레이션 예를 참조하십시오.)
비교적 큰 스키마 (약 150 개의 테이블)이지만 각 테이블 설명을 덤프하기 위해 오랫동안 걸리지 않아야한다고 확신합니다.
어쨌든 마지막을 가져 와서 속도를 높일 수 있습니까? schema.db
그리고 마이그레이션에 명시된 변경 사항을 적용합니까? 아니면이 스키마 덤프를 모두 건너 뛸 수 있습니까?
나는 이것을 이해한다 schema.db
매번 테스트 데이터베이스를 처음부터 작성하는 데 사용되지만이 경우에는 테이블 트리거에 데이터베이스 로직이 많이 포함되어 있습니다. schema.rb
어쨌든, 레이크 테스트는 어쨌든 우리에게 좋지 않습니다. (다른 시점에서 정리 해야하는 완전히 다른 문제입니다.)
dgs@dgs-laptop:~/rails/voyager$ time rake db:migrate (in /home/dgs/rails/voyager) == 20090227012452 AddModuleActionAndControllerNames: migrating ================ -- add_column(:modules, :action_name, :text) -> 0.9619s -> 0 rows -- add_column(:modules, :controller_name, :text) -> 0.1680s -> 0 rows == 20090227012452 AddModuleActionAndControllerNames: migrated (1.1304s) ======= real 87m12.961s user 0m12.949s sys 0m2.128s
해결책
모든 마이그레이션이 데이터베이스에 적용된 후 DB : Migrate Call DB : Schema : 덤프 작업을 수행하여 현재 데이터베이스 스키마에서 Schema.rb 파일을 생성합니다.
DB : Schema : 덤프 호출 어댑터의 "테이블"메소드를 덤프 모든 테이블 목록을 가져 오기위한 다음 각 테이블에 대해 "색인"메소드 및 "열"메소드를 호출합니다. ActivereCord-oracle_Enhanced-Adapter gem의 oracle_enhanced_adapter.rb 파일에서 이러한 메소드에서 사용되는 SQL Select 문을 찾을 수 있습니다. 기본적으로 모든 정보를 찾기 위해 모든% 또는 사용자% 데이터 사전 테이블 중에서 선택합니다.
처음에는 다양한 스키마가있는 데이터베이스와 함께 사용했을 때 오리지널 Oracle 어댑터에 문제가 있었으며 (성능이 스키마뿐만 아니라 데이터베이스의 총 테이블 수에 영향을받을 수 있기 때문에) Oracle Enhanced에서 일부 최적화를 수행했습니다. 어댑터. 귀하의 경우에 어떤 메소드가 느린 지 알아내는 것이 좋습니다 (각 테이블에 대해 실행되는 "인덱스"또는 "열"메소드 일 수 있습니다).
이 문제를 디버그하는 한 가지 방법은 oracle_enhanced_adapter.rb 파일에 디버그 메시지를 넣어서 얼마나 오랜 시간이 걸리는지 식별 할 수있는 방법입니다.
다른 팁
문제는 주로 파기 한 후에 대부분 해결되었습니다 oracle_enhanced_adapter.rb
.
로컬 스키마에서 문제가 너무 많은 테이블로 나왔습니다 (많은 EBA_%, EVT_%, EMP_%, SMP_%
테이블은 덤프에 아카이브 테이블이 포함되어 있고 데이터 사전에서 14 초가 걸리는 데이터 사전 중에서 테이블이 생성되었습니다.
속도를 고치기 위해 세 가지를 수행했습니다.
- 모든 불필요한 테이블을 떨어 뜨 렸습니다 (500 명 중 약 250 명)
- 스키마 덤프에서 제외 된 아카이브 테이블
- 오랜 쿼리의 결과를 캐시했습니다
이로 인해 나머지 350 개의 테이블의 마이그레이션/스키마 덤프에서 약 90 분에서 약 15 초의 시간이 개선되었습니다. 충분히 빠릅니다.
내 코드는 다음과 같은 코드입니다 (영감을 복사 및 붙여 넣지 않기 위해 -이 코드는 내 데이터베이스에 대해 상당히 구체적이지만 아이디어를 얻을 수 있어야합니다). 온도 테이블을 수동으로 만들어야합니다. 내가하는 데 약 2 ~ 3 분이 걸립니다 -마다마다마다 너무 길어지고, 어쨌든 상당히 정적입니다 =)
module ActiveRecord
module ConnectionAdapters
class OracleEnhancedAdapter
def tables(name = nil)
select_all("select lower(table_name) from all_tables where owner = sys_context('userenv','session_user') and table_name not like 'A!_%' escape '!' ").inject([]) do | tabs, t |
tabs << t.to_a.first.last
end
end
# TODO think of some way to automatically create the rails_temp_index table
#
# Table created by:
# create table rails_temp_index_table as
# SELECT lower(i.index_name) as index_name, i.uniqueness,
# lower(c.column_name) as column_name, i.table_name
# FROM all_indexes i, user_ind_columns c
# WHERE c.index_name = i.index_name
# AND i.owner = sys_context('userenv','session_user')
# AND NOT exists (SELECT uc.index_name FROM user_constraints uc
# WHERE uc.constraint_type = 'P' and uc.index_name = i.index_name);
def indexes(table_name, name = nil) #:nodoc:
result = select_all(<<-SQL, name)
SELECT index_name, uniqueness, column_name
FROM rails_temp_index_table
WHERE table_name = '#{table_name.to_s.upcase}'
ORDER BY index_name
SQL
current_index = nil
indexes = []
result.each do |row|
if current_index != row['index_name']
indexes << IndexDefinition.new(table_name, row['index_name'], row['uniqueness'] == "UNIQUE", [])
current_index = row['index_name']
end
indexes.last.columns << row['column_name']
end
indexes
end
end