InnoDB与MyIsam在频繁排序的MySQL 5.5表上

时间:2014-08-21 20:11:48

标签: mysql sorting innodb myisam

我有一张表(目前是InnoDB),大约有10万条记录。这些记录具有订单列,因此它们可以组成有序队列。实际上,这些记录属于大约40个有自己队列的部门,而这些部门又在这个表中有自己的记录。

问题在于我们不断地获得锁定等待时间"错误,因为各个部门同时对其队列(和记录)进行排序。

我知道MyIsam是一个table-level锁定引擎,而InnoDB是row-level。问题是我不确定哪种操作更快。

另一个原因是这个表与其他InnoDB表的各种查询相连,我不知道如果将表切换到MyIsam会发生什么。

这是表结构:

CREATE TABLE `ssti` (
    `demand_nber` MEDIUMINT(8) UNSIGNED NOT NULL COMMENT,
    `year` CHAR(4) NULL DEFAULT NULL COMMENT,
    `department` CHAR(4) NULL DEFAULT NULL COMMENT '4 caracteres',
    -- [other columns ]
    `priority` INT(10) UNSIGNED NOT NULL DEFAULT '9999999',
    PRIMARY KEY (`NR_DMD`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB;

这是更新优先级的java代码:

PreparedStatement psUpdatePriority = con.prepareStatement("UPDATE `ssti` SET `priority` = ? WHERE demand_nber=?;");

for (int i = 0; i < demands.length(); ++i) {                
    JSONObject d = demands.getJSONObject(i);                

    psUpdatePriority.setInt(1, d.getInt("newPriority"));
    psUpdatePriority.setInt(2, d.getInt("demandNumber"));
    psUpdatePriority.addBatch();                
}

int[] totalUpdated = psUpdatePriority.executeBatch();

2 个答案:

答案 0 :(得分:0)

在调查性能问题时,请务必使用slow query log,以便记录导致问题的特定查询。

这里的内容是您在WHERE子句中包含未编入索引的列。这对于大型数据集来说非常痛苦,因为它需要进行&#34;表扫描&#34;,或者读取每条记录并按顺序进行评估。

索引时,您的查询应该明显加快。

如果你真的碰壁,你可能想把每个部门分成他们自己的桌子。这很难撤消,所以我只追求这个作为最后的手段。

答案 1 :(得分:0)

Select语句通常不会相互阻塞。对每个查询分别在tempDB中进行排序。如果您正在等待锁定,那么请查看阻止选择的更新。

使用行锁定UPDATE将仅阻止所需(少量)行,允许其他语句访问其他行。使用表锁定时,UPDATE将阻止整个表,在UPDATE完成之前,其他任何语句都不会访问表。所以MyISAM无论如何都会让你的问题变得更糟。

-

您似乎将此表用于多种用途。因此,在调整此表的性能时,您需要考虑所有这些及其重要性。

案例1:部门查询自己的数据并需要排序

当多次重复使用某些数据操作的结果时,一般规则是保存它。它可以直接读取结果,而不是每次都计算它。 要允许查询读取已排序的数据,您需要创建索引。

然而,仅在排序列priority上的索引将无济于事。由于每个部门只能看到自己的数据,因此每个查询都包含部门编号。因此,您的索引应包含两个关键列KEY (department, priority)

案例2:表格已连接到其他几个表格

要使用JOIN加速查询,您需要的索引的键与用于连接的列相同。

案例3:插入新的,可能是交易的数据

单个表在处理新数据插入和处理报告查询的时间方面受到限制。通常,交易和报告用途被认为是彼此替代的。使用报告表是一种很好的做法,它汇总了事务表中的数据。聚合数据时,与维度的连接也更容易(行数较少)。