当使用UPDATE CASE WHEN保存重新排序列表时,MySQL挂起

时间:2014-01-22 19:31:04

标签: mysql sql

我正在使用MySQL UPDATE CASE WHEN ELSE语句更新我的网络应用程序上的有序列表。我有html table sortable drag-and-drop插件的stop eventservlet我点击了MySQL Table,新订单仍然存在MySQL

事情是,当用户非常快速地重新排序表时,22/01/2014 14:03:25 UPDATE `edited_table_name` SET `order` = CASE NR_DMD WHEN 92059 THEN 22 WHEN 124376 THEN 23 WHEN 124163 THEN 24 WHEN 127019 THEN 25 WHEN 123816 THEN 26 WHEN 124348 THEN 27 WHEN 127017 THEN 28 WHEN 126764 THEN 29 WHEN 126637 THEN 30 WHEN 122170 THEN 31 WHEN 125630 THEN 32 WHEN 125515 THEN 33 WHEN 124487 THEN 34 WHEN 124374 THEN 35 WHEN 124343 THEN 36 WHEN 124327 THEN 37 WHEN 126838 THEN 38 WHEN 126720 THEN 39 WHEN 126718 THEN 40 WHEN 123510 THEN 41 WHEN 122966 THEN 42 WHEN 124385 THEN 43 WHEN 122754 THEN 44 WHEN 124312 THEN 45 WHEN 122311 THEN 46 WHEN 121577 THEN 47 WHEN 121028 THEN 48 WHEN 123354 THEN 49 WHEN 121682 THEN 50 WHEN 120993 THEN 51 WHEN 120860 THEN 52 WHEN 120750 THEN 53 WHEN 120460 THEN 54 WHEN 120459 THEN 55 WHEN 120397 THEN 56 WHEN 119178 THEN 57 WHEN 111723 THEN 58 WHEN 127644 THEN 59 WHEN 127610 THEN 60 WHEN 127609 THEN 61 WHEN 127542 THEN 62 WHEN 125799 THEN 63 ELSE order END WHERE NR_DMD IN(92059,124376,124163,127019,123816,124348,127017,126764,126637,122170,125630,125515,124487,124374,124343,124327,126838,126720,126718,123510,122966,124385,122754,124312,122311,121577,121028,123354,121682,120993,120860,120750,120460,120459,120397,119178,111723,127644,127610,127609,127542,125799) 22/01/2014 14:03:25 UPDATE `edited_table_name` SET `order` = CASE NR_DMD WHEN 121419 THEN 10 WHEN 110378 THEN 11 WHEN 124376 THEN 12 WHEN 124163 THEN 13 WHEN 127019 THEN 14 WHEN 123816 THEN 15 WHEN 124348 THEN 16 WHEN 127017 THEN 17 WHEN 126764 THEN 18 WHEN 126637 THEN 19 WHEN 122170 THEN 20 WHEN 125630 THEN 21 WHEN 125515 THEN 22 WHEN 124487 THEN 23 WHEN 124374 THEN 24 WHEN 124343 THEN 25 WHEN 124327 THEN 26 WHEN 126838 THEN 27 WHEN 126720 THEN 28 WHEN 126718 THEN 29 WHEN 123510 THEN 30 WHEN 122966 THEN 31 WHEN 124385 THEN 32 WHEN 122754 THEN 33 WHEN 124312 THEN 34 WHEN 122311 THEN 35 WHEN 121577 THEN 36 ELSE order END WHERE NR_DMD IN(121419,110378,124376,124163,127019,123816,124348,127017,126764,126637,122170,125630,125515,124487,124374,124343,124327,126838,126720,126718,123510,122966,124385,122754,124312,122311,121577) 22/01/2014 14:03:25 UPDATE `edited_table_name` SET `order` = CASE NR_DMD WHEN 127585 THEN 21 WHEN 124376 THEN 22 WHEN 124163 THEN 23 WHEN 127019 THEN 24 WHEN 123816 THEN 25 WHEN 124348 THEN 26 WHEN 127017 THEN 27 WHEN 126764 THEN 28 WHEN 126637 THEN 29 WHEN 122170 THEN 30 WHEN 125630 THEN 31 WHEN 125515 THEN 32 WHEN 124487 THEN 33 WHEN 124374 THEN 34 WHEN 124343 THEN 35 WHEN 124327 THEN 36 WHEN 126838 THEN 37 WHEN 126720 THEN 38 WHEN 126718 THEN 39 WHEN 123510 THEN 40 WHEN 122966 THEN 41 WHEN 124385 THEN 42 WHEN 122754 THEN 43 WHEN 124312 THEN 44 WHEN 122311 THEN 45 WHEN 121577 THEN 46 WHEN 121028 THEN 47 WHEN 123354 THEN 48 WHEN 121682 THEN 49 WHEN 120993 THEN 50 WHEN 120860 THEN 51 WHEN 120750 THEN 52 WHEN 120460 THEN 53 WHEN 120459 THEN 54 WHEN 120397 THEN 55 WHEN 119178 THEN 56 WHEN 111723 THEN 57 WHEN 127644 THEN 58 WHEN 127610 THEN 59 WHEN 127609 THEN 60 ELSE order END WHERE NR_DMD IN(127585,124376,124163,127019,123816,124348,127017,126764,126637,122170,125630,125515,124487,124374,124343,124327,126838,126720,126718,123510,122966,124385,122754,124312,122311,121577,121028,123354,121682,120993,120860,120750,120460,120459,120397,119178,111723,127644,127610,127609) 22/01/2014 14:03:25 UPDATE `edited_table_name` SET `order` = CASE NR_DMD WHEN 127638 THEN 19 WHEN 127592 THEN 20 WHEN 124376 THEN 21 WHEN 124163 THEN 22 WHEN 127019 THEN 23 WHEN 123816 THEN 24 WHEN 124348 THEN 25 WHEN 127017 THEN 26 WHEN 126764 THEN 27 WHEN 126637 THEN 28 WHEN 122170 THEN 29 WHEN 125630 THEN 30 WHEN 125515 THEN 31 WHEN 124487 THEN 32 WHEN 124374 THEN 33 WHEN 124343 THEN 34 WHEN 124327 THEN 35 WHEN 126838 THEN 36 WHEN 126720 THEN 37 WHEN 126718 THEN 38 WHEN 123510 THEN 39 WHEN 122966 THEN 40 WHEN 124385 THEN 41 WHEN 122754 THEN 42 WHEN 124312 THEN 43 WHEN 122311 THEN 44 WHEN 121577 THEN 45 WHEN 121028 THEN 46 WHEN 123354 THEN 47 WHEN 121682 THEN 48 WHEN 120993 THEN 49 WHEN 120860 THEN 50 WHEN 120750 THEN 51 WHEN 120460 THEN 52 WHEN 120459 THEN 53 WHEN 120397 THEN 54 WHEN 119178 THEN 55 WHEN 111723 THEN 56 WHEN 127644 THEN 57 ELSE order END WHERE NR_DMD IN(127638,127592,124376,124163,127019,123816,124348,127017,126764,126637,122170,125630,125515,124487,124374,124343,124327,126838,126720,126718,123510,122966,124385,122754,124312,122311,121577,121028,123354,121682,120993,120860,120750,120460,120459,120397,119178,111723,127644) 会不时挂起。就像下面的例子一样,在同一秒发出了4个声明,然后它就被绞死了。

{{1}}

我认为MySQL会处理同一个表上的同时点击。但它看起来不是。也许这是表锁的一些问题。

如果你能以任何配置或技术给我任何建议,或者甚至是另一种更好的方法来坚持重新排序的清单,我会非常有帮助。

谢谢,

6 个答案:

答案 0 :(得分:1)

您可以尝试在servlet中的update语句之前使用以下会话参数。

“SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED”

这将允许如果两个语句几乎是即时发生的,即使另一个进程没有将它提交给服务器,它也会采用最新的语句。

当然,最好只在最终用户没有进行任何拖拽时才发送更改。下降超过X秒(即:2)并仅发送1个请求。这也可以解决问题。

答案 1 :(得分:1)

您是否考虑在客户端代码中使用某些内容,以便在重新排序列表时不会同时提交多个AJAX请求,例如setTimeout。

也许是这样的: http://benalman.com/code/projects/jquery-message-queuing/examples/ajax/

答案 2 :(得分:0)

我建议您检查一段时间不活动,当有大量不活动时,请将最新更新(具有累积更新)发送到服务器。

答案 3 :(得分:0)

在执行更新查询期间,InnoDB锁定它遍历的每一行以查找它正在修改的行。因此,为了减少锁定数量,您可以将查询拆分为两个单独的查询:

  1. 获取PRIMARY_KEY_LIST,假设edited_table_name的主键为id

    SELECT id FROM edited_table_name WHERE NR_DMD IN(...)

  2. 基于主键列表进行更新

    UPDATE edited_table_name SET order = CASE ... WHERE id IN(PRIMARY_KEY_LIST)

  3. 这将减少锁的数量,因为它减少了引擎必须遍历的行数。

    另一种选择是在NR_DMD

    上添加索引

答案 4 :(得分:0)

  

我可能有一个handler来限制在这种情况下可能来到servlet的命中:

  1. 我会将信息/详细信息存储在一个表格new_order_requests_table中,而不是立即应用每个新的订单请求。{/ li>
  2. 我会有一个flag由此处理程序相应地使用/更新其状态,例如:IdleUnder Progress等。
  3. 每当上述flag显示为Idle时,我会考虑应用new_order_requests_table中的最新行,并可能删除其中的所有早期行。
  4. 对于多个用户,您需要相应地修改上述内容。

      

    此外,当需要在单个语句中更新MySQL表中的许多行时,有时使用MyISAM进行表级锁定会比使用行级锁定的InnoDB更好。这是因为InnoDB可能会耗费相当长的时间来锁定和解锁那些行。

    您可以尝试在MyISAMInnoDB之间切换以找到更合适的引擎你的申请表。

答案 5 :(得分:0)

我认为你可以做到以下几点:

CREATE TEMPORARY TABLE Table1 (
     NR_DMD int NOT NULL);

INSERT INTO Table1 (NR_DMD)
   VALUES
(92059),(124376),(124163),(127019),(123816),(124348),(127017),(126764),(126637),
(122170),(125630),(125515),(124487),(124374),(124343),(124327),(126838),(126720),
(126718),(123510),(122966),(124385),(122754),(124312),(122311),(121577),(121028),
(123354),(121682),(120993),(120860),(120750),(120460),(120459),(120397),(119178),
(111723),(127644),(127610),(127609),(127542),(125799);

select * from Table1

22/01/2014 14:03:25 
UPDATE `edited_table_name
` SET `order` = CASE NR_DMD WHEN 92059 THEN 22 WHEN 124376 THEN 23 WHEN 124163 THEN 24 
WHEN 127019 THEN 25 WHEN 123816 THEN 26 WHEN 124348 THEN 27 WHEN 127017 THEN 28
WHEN 126764 THEN 29 WHEN 126637 THEN 30 WHEN 122170 THEN 31
WHEN 125630 THEN 32 WHEN 125515 THEN 33 WHEN 124487 THEN 34 
WHEN 124374 THEN 35 WHEN 124343 THEN 36 WHEN 124327 THEN 37 
WHEN 126838 THEN 38 WHEN 126720 THEN 39 WHEN 126718 THEN 40
WHEN 123510 THEN 41 WHEN 122966 THEN 42 WHEN 124385 THEN 43 
WHEN 122754 THEN 44 WHEN 124312 THEN 45 WHEN 122311 THEN 46
WHEN 121577 THEN 47 WHEN 121028 THEN 48 WHEN 123354 THEN 49
WHEN 121682 THEN 50 WHEN 120993 THEN 51 WHEN 120860 THEN 52 
WHEN 120750 THEN 53 WHEN 120460 THEN 54 WHEN 120459 THEN 55
WHEN 120397 THEN 56 WHEN 119178 THEN 57 WHEN 111723 THEN 58 
WHEN 127644 THEN 59 WHEN 127610 THEN 60 WHEN 127609 THEN 61 
WHEN 127542 THEN 62 WHEN 125799 THEN 63 ELSE order END 
WHERE NR_DMD IN(Select NR_DMD from Table1);

<强>要点:

1)创建临时表并插入第一次更新的值。

2)

UPDATE tablename SET ColName =CASE STATEMENT
       Where NR_DMD in ( SELECT NR_DMD FROM temp table)

3)对另外两个更新声明执行相同的操作。

我认为这会帮助你更好地表现。