此查询需要花费大量时间才能执行:
UPDATE facturacion2013_full a, facturacion2013_contadores b SET a.B1 = b.consumo WHERE a.contador = b.contador
这是我的表结构:
CREATE TABLE IF NOT EXISTS `facturacion2013_full` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`poliza` int(8) NOT NULL,
`contador` varchar(12) NOT NULL,
`B1` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fields_idx` (`contador`),
KEY `fields_iidx2` (`poliza`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
CREATE TABLE IF NOT EXISTS `facturacion2013_contadores` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`poliza` int(8) NOT NULL,
`contador` varchar(12) NOT NULL,
`consumo` int(8) NOT NULL,
PRIMARY KEY (`id`),
KEY `idx1` (`contador`),
KEY `idx2` (`poliza`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
我尝试过改变一些没有运气的小东西。还尝试更改mysql配置中的一些参数,如缓冲区大小,max_heap_table_size ...我缺少什么?提前谢谢!
答案 0 :(得分:2)
我在MySQL 5.6上测试了这个,它支持EXPLAIN for UPDATE语句。
mysql> explain UPDATE facturacion2013_full a JOIN facturacion2013_contadores b
ON a.contador = b.contador
SET a.B1 = b.consumo\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: a
type: ALL
possible_keys: fields_idx
key: NULL
key_len: NULL
ref: NULL
rows: 1
Extra: NULL
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: b
type: ref
possible_keys: idx1
key: idx1
key_len: 14
ref: test.a.contador
rows: 1
Extra: NULL
您可以看到它会读取表a
的所有行。我从表名中假设a
中的行数多于b
中的行数。因此它会从a
读取b
中是否存在匹配行的所有行。
也许它会为MySQL节省一些工作来重新排序表,以便它读取较小表的所有行,并且只匹配较大表中的行。
mysql> explain UPDATE facturacion2013_contadores b JOIN facturacion2013_full a
ON a.contador = b.contador
SET a.B1 = b.consumo\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: b
type: ALL
possible_keys: idx1
key: NULL
key_len: NULL
ref: NULL
rows: 1
Extra: NULL
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: a
type: ref
possible_keys: fields_idx
key: fields_idx
key_len: 14
ref: test.b.contador
rows: 1
Extra: NULL
表的顺序不应该重要,因为优化器应该能够自己重新排序表,必要时以更好的顺序读取它们。但有时候优化器并不像我们想的那么聪明。或者它甚至可能以一种使查询更糟的方式对表格进行重新排序。你正在使用MySQL 5.1,这是非常古老的(事实上它支持的生命周期截至2013年12月31日),所以也许优化器不如新版本好。
您可以使用STRAIGHT_JOIN
关键字覆盖优化程序并强制按照您在查询中为其提供的顺序读取表格:
mysql> explain UPDATE facturacion2013_contadores b STRAIGHT_JOIN facturacion2013_full a
ON a.contador = b.contador
SET a.B1 = b.consumo\G
对于它的价值,您还可以在MySQL 5.1上测试UPDATE语句的优化。为了了解优化器将如何分析它,将任何UPDATE语句重写为等效的SELECT非常简单。只需将SET表达式移动到选择列表中即可。
mysql> explain SELECT a.B1 = b.consumo FROM facturacion2013_full a
JOIN facturacion2013_contadores b ON a.contador = b.contador\G