我们的Access 2010数据库最近达到了2GB的文件大小限制,因此我将数据库移植到了MySQL。
我在Windows Server 2008 x64上安装了MySQL Server 5.6.1 x64。 已加载所有操作系统更新和修补程序。
我正在使用MySQL ODBC 5.2w x64驱动程序,因为它似乎是最快的。
我的盒子有一个i7-3960X,64GB RAM和480GB SSD。
我使用Access Query Designer,因为我更喜欢接口,我经常需要将缺少的记录从一个表附加到另一个表。
作为测试,我有一个带有两个链接表的简单Access数据库:
tblData链接到另一个Access数据库和
tblOnline将SYSTEM DSN用于链接的ODBC表。
两个表都包含超过1000万条记录。 我的一些移植工作表已经拥有超过3000万条记录。
要选择要追加的记录,我使用一个名为INDBYN的字段,该字段为true或false。
首先,我在tblData上运行Update查询:
UPDATE tblData SET tblData.InDBYN = False;
然后我更新所有匹配的记录:
UPDATE tblData INNER JOIN tblData ON tblData.IDMaster = tblOnline.IDMaster SET tblData.InDBYN = True;
这种方法工作得相当快,甚至连接到ODBC表。
最后,我将INDBYN为假的所有记录追加到tblOnline。 这也是可接受的速度,虽然慢于附加到链接访问表。
在Access中,一切都可以100%运行并且速度非常快,除了数据库太大了。
在链接访问表上,更新11,500,000条记录需要2分15秒。
但是,我现在需要将SOURCE表移动到MySQL,因为它达到了2GB的限制。
因此将来我需要在链接的ODBC表上运行UPDATE语句。
到目前为止,当我在链接的ODBC表上运行相同的简单UPDATE查询时,它运行超过20分钟,然后炸弹说该查询已超过2GB内存限制。
两个表的结构相同。
我不知道如何解决这个问题,请提供建议。
我更喜欢使用Access作为前端,因为我已经为应用程序设计了数百个查询,并且没有时间重新开发应用程序。
我使用InnoDB引擎并尝试了各种调整但没有成功。由于我的数据库使用关系表,因此它似乎是使用INNODB而不是MyISAM的最佳选择。
我已经打开和关闭双重写入并尝试了各种缓冲池大小,包括查询缓存。它对此特定查询没有任何影响。
我当前的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 :(得分:1)
通过链接表与MS Access进行通信的速度很慢。非常慢。这是无法改变的事实。为什么会这样?访问首先从MySQL加载数据,然后处理命令,最后将数据放回。另外,它一行一行地完成这个过程! 但是,如果您不需要在“更新”查询中使用本地表中的参数或数据,则可以避免这种情况。 (换句话说 - 如果您的查询始终相同且仅使用MySQL数据)
Trick是强制MySQL服务器处理查询而不是Access!这可以通过在Access 中创建“pass-thru”查询来实现,您可以在其中直接编写SQL代码(在MySQL语法中)。 Access然后将此命令发送到MySQL服务器,并在该服务器内直接处理。所以你的查询几乎和在本地访问表中一样快。
答案 1 :(得分:0)
Access是单用户系统。带有InnoDB的MySQL是一个受事务保护的多用户系统。
当您发出命中大约10个megarows的UPDATE
命令时,MySQL必须构造回滚信息,以防操作在到达所有行之前失败。这需要大量的时间和记忆。
如果要执行这些真正庞大的UPDATE
和INSERT
命令,请尝试将表格访问方法切换到MyISAM。 MyISAM不受事务保护,因此这些操作可能运行得更快。
您可能会发现使用ODBC之外的某些工具进行数据迁移很有帮助。正如您所发现的,ODBC在处理大量数据方面受到严重限制。例如,您可以将Access表导出为平面文件,然后使用MySQL客户端程序导入它们。见这里...... https://stackoverflow.com/questions/9185/what-is-the-best-mysql-client-application-for-windows
将数据导入MySQL后,即可运行基于访问的查询。但是要避免命中数据库中所有内容的UPDATE
个请求。
答案 2 :(得分:0)
Ollie,我明白你要避免触及所有行的UPDATES。我使用它来标记目标数据库中缺少的行,并且它只是一种快速简单的方法来仅追加丢失的行。我看到SQLyog有一个导入工具只能添加新记录,但这仍然会在导入表中的所有行中运行,并运行数小时。我将看看我是否只能将我想要的数据导出为CSV,但如果可能的话,仍然可以让ODBC连接器比现有的更快地工作。