jba*_*sta 7 mysql database indexing performance insert
我正在使用和使用MySQL作为后端引擎的软件(它可以使用其他如PostgreSQL或Oracle或SQLite,但这是我们正在使用的主要应用程序).该软件的设计方式使得我们要访问的二进制数据在各列中保持为BLOB(每个表有一个BLOB列,其他列有整数/浮点数来表征BLOB,另一列有BLOB的字符串列)MD5哈希).这些表通常有2,3或4个索引,其中一个索引始终是MD5列UNIQUE
.有些表已经有数百万个条目,并且它们已经输入了数千兆字节的大小.我们在同一台服务器中保留了每年独立的MySQL数据库(到目前为止).对于一般应用程序(Dell PowerEdge 2U格式服务器),硬件非常合理(我认为).
MySQL SELECT
查询相对较快.那里几乎没有抱怨,因为这些是(大部分时间)处于批处理模式.但是,INSERT
查询需要很长时间,随着表大小(行数)的增加而增加.不可否认,这是因为MD5列是类型的UNIQUE
,因此每个INSERT
都必须弄清楚每个新行是否具有相应的,已经插入的MD5字符串.如果有其他索引(不是唯一的),如果性能变差,那就不奇怪了(我认为).但是我仍然不能放下心来这个软件架构的选择(我怀疑BLOB在表行而不是磁盘中有显着的负面影响)并不是最好的选择.插入并不重要,但这是一种烦人的感觉.
有没有人有类似情况的经验?使用MySQL,甚至是其他(最好是基于Linux的)RDBM?你想提供的任何见解,也许是一些表现数据?
顺便说一句,工作语言是C++(它包含C调用MySQL的API).
dim*_*mus 10
可能是水平分区和将blob字段移动到单独的表中的时间.在本文的"关于垂直分区的快速侧注"中,作者从表中删除了一个较大的varchar字段,它提高了查询的速度.
原因是如果要覆盖的空间较少,则磁盘上数据的物理遍历会变得非常快,因此在其他地方移动更大的字段会提高性能.
另外(你可能已经这样做了)将索引列的大小减小到绝对最小值(在md5的ascii编码中为char(32))是有益的,因为键的大小与其使用的速度成正比.
如果您使用InnoDB表一次执行多次插入,则可以通过将插入包装到事务中并在一个查询中执行mupliple插入来显着提高插入速度:
START TRANSACTION
INSERT INTO x (id, md5, field1, field2) values (1, '123dab...', 'data1','data2'),(2,'ab2...','data3','data4'),.....;
COMMIT
Run Code Online (Sandbox Code Playgroud)
请参阅INSERT语句的速度.你经常碰到MD5吗?我相信这些不应该发生太多次,所以也许你可以使用类似INSERT ...... ON DUPLICATE来处理碰撞.如果您有特定的插入期间,则可以在插入时禁用密钥,并在以后恢复它们.另一种选择是使用复制,使用主机进行插入,使用从机进行选择.