2013-04-17 7 views
1

Access 2010 데이터베이스가 최근 2GB 파일 크기 제한에 도달하여 데이터베이스를 MySQL로 포팅했습니다.MySQL ODBC 업데이트 쿼리가 매우 느림

Windows Server 2008 x64에 MySQL Server 5.6.1 x64가 설치되었습니다. 모든 OS 업데이트 및 패치가로드됩니다.

MySQL ODBC 5.2w x64 드라이버를 사용하고 있습니다. 가장 빠른 것 같습니다.

내 상자에는 64GB RAM 및 480GB SSD가있는 i7-3960X가 있습니다.

필자는 인터페이스를 선호하며 정기적으로 누락 된 레코드를 한 테이블에서 다른 테이블로 추가해야하므로 Access Query Designer를 사용합니다.

tblData의 또 다른 Access 데이터베이스에 대한 링크와

tblOnline가 연결된 ODBC 테이블에 시스템 DSN을 사용하여 테스트로

, 나는 두 개의 연결된 테이블과 간단한 Access 데이터베이스가 있습니다.

두 테이블 모두 1,000 만 개가 넘는 레코드가 있습니다. 포팅 된 작업 테이블 중 일부는 이미 3 천만 개가 넘는 레코드가 있습니다.

추가 할 레코드를 선택하려면 INDBYN이라는 필드를 true 또는 false로 사용합니다.

먼저 나는 tblData에 업데이트 쿼리를 실행

UPDATE tblData SET tblData.InDBYN = False; 

가 그럼 난 일치하는 모든 레코드를 업데이트 :이 경우에도 연결된 ODBC 테이블에 합리적으로 빠르게 작동

UPDATE tblData INNER JOIN tblData ON tblData.IDMaster = tblOnline.IDMaster SET tblData.InDBYN = True; 

.

마지막으로 나는 INDBYN이 거짓 인 모든 레코드를 tblOnline에 추가합니다. 링크 된 액세스 테이블에 추가하는 속도보다 느리지 만 속도에도 사용할 수 있습니다.

액세스 내 모든 것이 100 % 작동하며 DB가 너무 커지는 것을 제외하면 엄청나게 빠릅니다.

연결된 액세스 테이블에서 11,500,000 개의 레코드를 업데이트하는 데 2m15s가 걸립니다.

그러나 이제는 원본 테이블을 MySQL로 이동해야합니다 (2GB 제한에 도달했습니다).

앞으로는 연결된 ODBC 테이블에서 UPDATE 문을 실행해야합니다.

지금까지 연결된 ODBC 테이블에서 동일한 간단한 UPDATE 쿼리를 실행하면 20 분 이상 실행 된 후 쿼리가 2GB 메모리 제한을 초과했다는 내용이 나오는 것으로 나타났습니다.

두 테이블의 구조는 동일합니다.

이 문제를 해결하는 방법을 모르므로 조언을 구하십시오.

나는 앱을 위해 이미 설계된 수백 가지 쿼리를 가지고 있기 때문에 Access를 프론트 엔드로 사용하는 것을 선호합니다. 앱을 다시 개발할 시간이 없습니다.

나는 InnoDB 엔진을 사용하고 성공하지 못한 채 다양한 시도를 해왔다. 데이터베이스가 관계형 테이블을 사용하기 때문에 MyISAM과는 반대로 INNODB를 사용하는 것이 가장 좋은 옵션처럼 보였다.

이중 쓰기 기능을 켜고 끄고 쿼리 캐시를 포함하여 다양한 버퍼 풀 크기를 시도했습니다. 이 특정 쿼리에는 차이가 없습니다.

나의 현재의 my.ini 파일은 다음과 같습니다 :

#----------------------------------------------------------------------- 
# MySQL Server Instance Configuration File 
# ---------------------------------------------------------------------- 

[client] 
no-beep 

port=3306 

[mysql] 

default-character-set=utf8 

server_type=3 
[mysqld] 

port=3306 

basedir="C:\Program Files\MySQL\MySQL Server 5.6\" 

datadir="E:\MySQLData\data\" 

character-set-server=utf8 

default-storage-engine=INNODB 

sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" 

log-output=FILE 
general-log=0 
general_log_file="SQLSERVER.log" 
slow-query-log=1 
slow_query_log_file="SQLSERVER-slow.log" 
long_query_time=10 

log-error="SQLSERVER.err" 

max_connections=100 

query_cache_size = 20M 

table_open_cache=2000 

tmp_table_size=502M 

thread_cache_size=9 

myisam_max_sort_file_size=100G 

myisam_sort_buffer_size=1002M 

key_buffer_size=8M 

read_buffer_size=64K 
read_rnd_buffer_size=256K 

sort_buffer_size=256K 

innodb_additional_mem_pool_size=32M 

innodb_flush_log_at_trx_commit = 1 

innodb_log_buffer_size=16M 

innodb_buffer_pool_size = 48G 

innodb_log_file_size=48M 

innodb_thread_concurrency = 0 

innodb_autoextend_increment=64M 

innodb_buffer_pool_instances=8 

innodb_concurrency_tickets=5000 

innodb_old_blocks_time=1000 

innodb_open_files=2000 

innodb_stats_on_metadata=0 

innodb_file_per_table=1 

innodb_checksum_algorithm=0 

back_log=70 

flush_time=0 

join_buffer_size=256K 

max_allowed_packet=4M 

max_connect_errors=100 

open_files_limit=4110 

query_cache_type = 1 

sort_buffer_size=256K 

table_definition_cache=1400 

binlog_row_event_max_size=8K 

sync_relay_log=10000 
sync_relay_log_info=10000 

tmpdir = "G:/MySQLTemp" 
innodb_write_io_threads = 16 
innodb_doublewrite 
innodb = ON 
innodb_fast_shutdown = 1 

query_cache_min_res_unit = 4096 

query_cache_limit = 1048576 

innodb_data_home_dir = "E:/MySQLData/data" 

bulk_insert_buffer_size = 8388608 

어떤 조언이 크게 감사합니다. 미리 감사드립니다.

+0

20 분 이상 걸리며 실행하려고하는 쿼리는 다음과 같습니다. 'UPDATE tblData SET tblData.InDBYN = False;' 위에서 언급 한 것처럼 링크 된 ODBC 테이블에서. – dbDesigner

답변

0

액세스는 단일 사용자 시스템입니다. InnoDB와 MySQL은 트랜잭션으로 보호되는 다중 사용자 시스템이다.

메가 로우를 공격하는 UPDATE 명령을 내리면, MySQL은 모든 행을 치기 전에 조작이 실패 할 경우 롤백 정보를 구성해야합니다. 이것은 많은 시간과 기억을 필요로합니다.

이 엄청난 수의 UPDATEINSERT 명령을 사용하려는 경우 테이블 액세스 방법을 MyISAM으로 전환 해보십시오. MyISAM은 트랜잭션으로 보호되지 않으므로 이러한 작업이 더 빨리 수행 될 수 있습니다.

ODBC가 아닌 다른 도구를 사용하여 데이터를 마이그레이션하는 것이 도움이 될 수 있습니다. ODBC는 많은 데이터를 처리 할 수있는 능력이 매우 제한되어 있습니다. 예를 들어 Access 테이블을 플랫 파일로 내 보낸 다음 MySQL 클라이언트 프로그램을 사용하여 가져올 수 있습니다. 여기를 참조하십시오 ... https://stackoverflow.com/questions/9185/what-is-the-best-mysql-client-application-for-windows

일단 데이터를 MySQL로 가져 오면 액세스 기반 쿼리를 실행할 수 있습니다. 그러나 UPDATE 요청이 데이터베이스의 모든 것을 공격하지 않도록하십시오.

+0

Thanks Ollie, 나는 BullZip을 사용하여 원래 데이터를 MySQL로 가져 왔으며, 실행에는 약 18 시간이 걸렸습니다. 그런 다음 SQLyog를 구입하고 더 빨리 실행되는 데이터 가져 오기 도구를 사용했습니다.흥미롭게도, MySQL Workbech 내에서 UPDATE 쿼리를 실행했으며 11,552,802 개의 행을 업데이트하는 데 104.785 초 밖에 걸리지 않았습니다. 이것은 Access의 2 분 15 초보다 훨씬 빠릅니다. 하지만 먼저 안전 업데이트를 사용 중지해야했습니다. 이제는 ODBC 커넥터의 매개 변수를 사용하여 더 빠르게 작동하도록 할 수 있는지 확인하고 있습니다. 대형 데이터베이스에 대해 더 잘 작동하도록하는 방법에 대한 제안 사항이 있으면 알려주십시오. – dbDesigner

0

좋아요, 나는 모든 행을 치는 업데이트를 피하는 것에 중점을 둡니다. 나는 그것을 대상 데이터베이스에서 누락 된 행에 플래그를 지정하는 데 사용하며 누락 된 행만 추가하는 빠르고 쉬운 방법이었습니다. SQLyog에는 가져 오기 도구가있어 새로운 레코드 만 추가 할 수 있지만 여전히 가져 오기 테이블의 모든 행을 실행하고 몇 시간 동안 실행됩니다. 내가 CSV에 원하는 데이터 만 내보낼 수 있는지 알게되지만 가능한 경우 ODBC 커넥터가 현재보다 빠르게 작동하도록하는 것이 좋습니다.

1

링크 된 테이블을 통한 MySQL과 MS Access의 통신이 느립니다. 몹시 천천히. 이것이 바뀔 수없는 사실입니다. 왜 그런가? 먼저 MySQL에서 데이터를로드 한 다음 명령을 처리하고 마지막으로 데이터를 다시 저장합니다. 또한이 프로세스를 행별로 수행합니다! 그러나 "업데이트"쿼리에서 로컬 테이블의 매개 변수 나 데이터를 사용할 필요가없는 경우에는이 문제를 피할 수 있습니다. (다른 말로 - 쿼리가 항상 같고 MySQL 데이터 만 사용하는 경우)

트릭은 MySQL 서버가 Access 대신 쿼리를 처리하도록 강제하는 것입니다! 액세스에 "pass-thru"쿼리를 작성하여 을 만들면 SQL 코드를 직접 작성할 수 있습니다 (MySQL 구문). 그런 다음 Access는이 명령을 MySQL 서버로 보내고 해당 서버 내에서 직접 처리됩니다. 따라서 쿼리는 로컬 액세스 테이블에서 수행하는 것만큼이나 빠릅니다.