我有一张表(目前是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();
答案 0 :(得分:0)
在调查性能问题时,请务必使用slow query log,以便记录导致问题的特定查询。
这里的内容是您在WHERE
子句中包含未编入索引的列。这对于大型数据集来说非常痛苦,因为它需要进行&#34;表扫描&#34;,或者读取每条记录并按顺序进行评估。
索引时,您的查询应该明显加快。
如果你真的碰壁,你可能想把每个部门分成他们自己的桌子。这很难撤消,所以我只追求这个作为最后的手段。
答案 1 :(得分:0)
Select语句通常不会相互阻塞。对每个查询分别在tempDB中进行排序。如果您正在等待锁定,那么请查看阻止选择的更新。
使用行锁定UPDATE
将仅阻止所需(少量)行,允许其他语句访问其他行。使用表锁定时,UPDATE
将阻止整个表,在UPDATE
完成之前,其他任何语句都不会访问表。所以MyISAM无论如何都会让你的问题变得更糟。
-
您似乎将此表用于多种用途。因此,在调整此表的性能时,您需要考虑所有这些及其重要性。
案例1:部门查询自己的数据并需要排序
当多次重复使用某些数据操作的结果时,一般规则是保存它。它可以直接读取结果,而不是每次都计算它。 要允许查询读取已排序的数据,您需要创建索引。
然而,仅在排序列priority
上的索引将无济于事。由于每个部门只能看到自己的数据,因此每个查询都包含部门编号。因此,您的索引应包含两个关键列KEY (department, priority)
。
案例2:表格已连接到其他几个表格
要使用JOIN
加速查询,您需要的索引的键与用于连接的列相同。
案例3:插入新的,可能是交易的数据
单个表在处理新数据插入和处理报告查询的时间方面受到限制。通常,交易和报告用途被认为是彼此替代的。使用报告表是一种很好的做法,它汇总了事务表中的数据。聚合数据时,与维度的连接也更容易(行数较少)。