删除和插入需要很长时间在MySQL(InnoDB)

时间:2016-01-17 15:54:13

标签: mysql database innodb database-performance query-performance

我有一组数字,而且其中的每个数字都与它相关的数字很少。所以我将它存储在这样的表中:

NUMBERS  ASSOCIATEDNUMBERS
1        3
1        7
1        8
2        11
2        7
7        9
8        13
11       17
14       18
17       11
17       18

因此,它是一个具有许多相关数字的数字,反之亦然。两列都已编入索引。 (从而使我能够找到数字及其相关数字,反之亦然)

我的创建表如下所示:

CREATE TABLE `TABLE_B` (
  `NUMBERS` bigint(20) unsigned NOT NULL,
  `ASSOCIATEDNUMBERS` bigint(20) unsigned NOT NULL,
  UNIQUE KEY `unique_number_associatednumber_constraint` (`NUMBERS`,`ASSOCIATEDNUMBERS`),
  KEY `fk_AssociatedNumberConstraint` (`ASSOCIATEDNUMBERS`),
  CONSTRAINT `fk_AssociatedNumberConstraint` FOREIGN KEY (`ASSOCIATEDNUMBERS`) REFERENCES `table_a` (`SRNO`),
  CONSTRAINT `fk_NumberConstraint` FOREIGN KEY (`NUMBERS`) REFERENCES `table_a`` (`SRNO`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

此处TABLE_A的列SRNOAUTO_INCREMENT PRIMARY KEY,并且是表格中的第一个列。 (根据MySQL手册,由于外键约束自动定义,我无法在TABLE_B.NUMBERSTABLE_B.ASSOCIATEDNUMBERS上定义索引。

问题:

每当我需要为一个数字更改ASSOCIATEDNUMBERS时(在“NUMBERS'”中)我只是从表中删除该数字的现有行:

DELETE FROM TABLE_B WHERE NUMBERS= ?

然后为新的ASSOCIATEDNUMBERS集合插入行:

INSERT INTO TABLE_B (NUMBERS, ASSOCIATEDNUMBERS) VALUES ( ?, ?), (?, ?), (?, ?), ...

然而,这需要很长时间。特别是在我的多线程应用程序中,我打开多个连接(每个线程每个线程)到数据库,每个连接运行在两个查询之上(但每个查询具有不同的数字)。

例如,如果我打开40个连接,每个连接删除现有连接并插入250个新关联号码,则需要10到15秒。如果我增加连接数,时间也会增加。

其他信息:

SHOW GLOBAL STATUS LIKE 'Threads_running';

最多显示40个主题。

Innodb参数:

innodb_adaptive_flushing, ON
innodb_adaptive_flushing_lwm, 10
innodb_adaptive_hash_index, ON
innodb_adaptive_max_sleep_delay, 150000
innodb_additional_mem_pool_size, 2097152
innodb_api_bk_commit_interval, 5
innodb_api_disable_rowlock, OFF
innodb_api_enable_binlog, OFF
innodb_api_enable_mdl, OFF
innodb_api_trx_level, 0
innodb_autoextend_increment, 64
innodb_autoinc_lock_mode, 1
innodb_buffer_pool_dump_at_shutdown, OFF
innodb_buffer_pool_dump_now, OFF
innodb_buffer_pool_filename, ib_buffer_pool
innodb_buffer_pool_instances, 8
innodb_buffer_pool_load_abort, OFF
innodb_buffer_pool_load_at_startup, OFF
innodb_buffer_pool_load_now, OFF
innodb_buffer_pool_size, 1073741824
innodb_change_buffer_max_size, 25
innodb_change_buffering, all
innodb_checksum_algorithm, crc32
innodb_checksums, ON
innodb_cmp_per_index_enabled, OFF
innodb_commit_concurrency, 0
innodb_compression_failure_threshold_pct, 5
innodb_compression_level, 6
innodb_compression_pad_pct_max, 50
innodb_concurrency_tickets, 5000
innodb_data_file_path, ibdata1:12M:autoextend
innodb_data_home_dir, 
innodb_disable_sort_file_cache, OFF
innodb_doublewrite, ON
innodb_fast_shutdown, 1
innodb_file_format, Antelope
innodb_file_format_check, ON
innodb_file_format_max, Antelope
innodb_file_per_table, ON
innodb_flush_log_at_timeout, 1
innodb_flush_log_at_trx_commit, 2
innodb_flush_method, normal
innodb_flush_neighbors, 1
innodb_flushing_avg_loops, 30
innodb_force_load_corrupted, OFF
innodb_force_recovery, 0
innodb_ft_aux_table, 
innodb_ft_cache_size, 8000000
innodb_ft_enable_diag_print, OFF
innodb_ft_enable_stopword, ON
innodb_ft_max_token_size, 84
innodb_ft_min_token_size, 3
innodb_ft_num_word_optimize, 2000
innodb_ft_result_cache_limit, 2000000000
innodb_ft_server_stopword_table, 
innodb_ft_sort_pll_degree, 2
innodb_ft_total_cache_size, 640000000
innodb_ft_user_stopword_table, 
innodb_io_capacity, 200
innodb_io_capacity_max, 2000
innodb_large_prefix, OFF
innodb_lock_wait_timeout, 50
innodb_locks_unsafe_for_binlog, OFF
innodb_log_buffer_size, 268435456
innodb_log_compressed_pages, ON
innodb_log_file_size, 262144000
innodb_log_files_in_group, 2
innodb_log_group_home_dir, .\
innodb_lru_scan_depth, 1024
innodb_max_dirty_pages_pct, 75
innodb_max_dirty_pages_pct_lwm, 0
innodb_max_purge_lag, 0
innodb_max_purge_lag_delay, 0
innodb_mirrored_log_groups, 1
innodb_monitor_disable, 
innodb_monitor_enable, 
innodb_monitor_reset, 
innodb_monitor_reset_all, 
innodb_old_blocks_pct, 37
innodb_old_blocks_time, 1000
innodb_online_alter_log_max_size, 134217728
innodb_open_files, 300
innodb_optimize_fulltext_only, OFF
innodb_page_size, 16384
innodb_print_all_deadlocks, OFF
innodb_purge_batch_size, 300
innodb_purge_threads, 1
innodb_random_read_ahead, OFF
innodb_read_ahead_threshold, 56
innodb_read_io_threads, 64
innodb_read_only, OFF
innodb_replication_delay, 0
innodb_rollback_on_timeout, OFF
innodb_rollback_segments, 128
innodb_sort_buffer_size, 1048576
innodb_spin_wait_delay, 6
innodb_stats_auto_recalc, ON
innodb_stats_method, nulls_equal
innodb_stats_on_metadata, OFF
innodb_stats_persistent, ON
innodb_stats_persistent_sample_pages, 20
innodb_stats_sample_pages, 8
innodb_stats_transient_sample_pages, 8
innodb_status_output, OFF
innodb_status_output_locks, OFF
innodb_strict_mode, OFF
innodb_support_xa, ON
innodb_sync_array_size, 1
innodb_sync_spin_loops, 30
innodb_table_locks, ON
innodb_thread_concurrency, 0
innodb_thread_sleep_delay, 10000
innodb_undo_directory, .
innodb_undo_logs, 128
innodb_undo_tablespaces, 0
innodb_use_native_aio, OFF
innodb_use_sys_malloc, ON
innodb_version, 5.6.28
innodb_write_io_threads, 16

更新

这是" SHOW ENGINE InnoDB状态"输出:http://pastebin.com/raw/E3rK4Pu5

UPDATE2:

背后的原因是其他地方而不是DB。我的代码中的一些其他功能是占用大量CPU导致MySQL(在同一台机器上运行)变慢。感谢您的所有答案和帮助。

1 个答案:

答案 0 :(得分:0)

在删除/插入之前,您似乎正在获取行/表上的锁定,这就是导致问题的原因。

检查

SELECT * from information_schema.GLOBAL_VARIABLES;

另外,使用

检查表上的锁定
SHOW OPEN TABLES  from <database name> where In_use>0

并使用

锁定类型
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS

因此,当您运行查询时,请在监视中添加这些查询,您也可以使用tee命令将其存储在文件中。

所以,还有一件事可以导致这种情况,虽然你已经为列编制了索引,但是如果数据读取this有限制,则mysql存在限制。

读取此内容以安装watch http://osxdaily.com/2010/08/22/install-watch-command-on-os-x/并运行时间延迟为1秒的watch脚本,然后在watch中运行mysql查询,如果要将其存储在file use tee命令中,然后在文件中写入输出。您可以拖尾来获取文件中的数据