我有一个存储 MD5 哈希的索引列。因此,该列将始终存储 32 个字符的值。无论出于何种原因,它都是作为 varchar 而不是 char 创建的。迁移数据库以将其转换为字符是否值得?这是在带有 InnoDB 的 MySQL 5.0 中。
前言
我们的应用程序运行多个DELETE并行执行查询的线程。查询影响孤立的数据,即不应该存在并发DELETE发生在来自不同线程的相同行上的可能性。但是,根据文档,MySQL 对DELETE语句使用所谓的“next-key”锁,它同时锁定匹配的键和一些间隙。这会导致死锁,我们找到的唯一解决方案是使用READ COMMITTED隔离级别。
问题
DELETE使用JOIN大表执行复杂语句时会出现问题。在特定情况下,我们有一个带有警告的表,只有两行,但查询需要从两个单独的INNER JOINed 表中删除属于某些特定实体的所有警告。查询如下:
DELETE pw
FROM proc_warnings pw
INNER JOIN day_position dp
ON dp.transaction_id = pw.transaction_id
INNER JOIN ivehicle_days vd
ON vd.id = dp.ivehicle_day_id
WHERE vd.ivehicle_id=? AND dp.dirty_data=1
Run Code Online (Sandbox Code Playgroud)
当 day_position 表足够大时(在我的测试用例中有 1448 行),那么即使使用READ COMMITTED隔离模式,任何事务也会阻塞整个 proc_warnings表。
该问题始终在此示例数据上重现 - http://yadi.sk/d/QDuwBtpW1BxB9在 MySQL 5.1(在 5.1.59 上检查)和 MySQL 5.5(在 MySQL 5.5.24 上检查)中。
编辑:链接的示例数据还包含查询表的架构和索引,为方便起见,在此处复制:
CREATE TABLE `proc_warnings` (
`id` int(11) NOT NULL AUTO_INCREMENT, …Run Code Online (Sandbox Code Playgroud) 在我粗略的研究过程中,我无法找到有关SELECT INTO OUTFILE超过INSERT INTO ... SELECT. 在阅读与InnoDB 表上的相关锁相关的文档时,INSERT INTO ... SELECT它指出:
在插入到 T 的每一行上设置一个没有间隙锁的排他索引记录。 如果事务隔离级别为 READ COMMITTED 或启用了 innodb_locks_unsafe_for_binlog,并且事务隔离级别不是 SERIALIZABLE,则 InnoDB 将 S 上的搜索作为一致读(不锁)。否则,InnoDB 会在来自 S 的行上设置共享的 next-key 锁。
为了避免锁定INSERT INTO ... SELECT似乎我必须确保隔离级别是READ COMMITTED为了避免在查询过程中锁定源表。
但是,我无法找到任何有关锁和使用的权威答案SELECT INTO OUTFILE,甚至没有找到MySQL文档参考锁信息。
我的目标是避免在查询运行时锁定源表以避免连接堆叠。
我需要使用 LOAD DATA INFILE 将 400 万行数据加载到 MySQL InnoDB 表中,并且想知道是否有我可以调整的服务器配置选项以获得更快的加载。
我花了 15 分钟来加载 200 万行,我认为 LOAD DATA INFILE 的性能令人失望。我的声明看起来像这样
LOAD DATA LOCAL INFILE 'path/file.csv' INTO TABLE table FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' IGNORE 1 LINES (column1, column2, etc);