【发布时间】:2011-07-30 07:03:02
【问题描述】:
我一直在尝试对某个 SELECT 查询进行一些速度改进。 情况如下: 有一个(在我眼里)巨大的交叉表。它目前有大约 2000 万行,但我预计这会增长很多。 基于这个交叉表,我需要创建另一个表。为此,我需要执行以下查询:
SELECT hugeCrossingTable.field3, otherTable.field1, hugeCrossingTable.field2 * otherTable.field3 AS someName
FROM hugeCrossingTable
INNER JOIN otherTable ON hugeCrossingTable.field1 = otherTable.field2
现在这会产生大约一百万行。我已经在 2 个表中的两个 field1 上都有索引,但是仍然需要 18 分钟才能完成.. 我考虑过拆分表,但后来我需要找到一种方法来拆分数据,因为它只是一个交叉表,所以没有想到如何做到这一点。
关于如何优化它的任何想法?
谢谢。
根据要求,这里是创建语句:
CREATE TABLE `hugeCrossingTable` (
`field` int(11) NOT NULL,
`field1` int(11) NOT NULL,
`field2` double(10,5) DEFAULT NULL,
`field3` int(4) DEFAULT NULL,
KEY `field1` (`field1`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `otherTable` (
`field` int(10) unsigned NOT NULL AUTO_INCREMENT,
`field1` int(10) unsigned NOT NULL,
`field2` int(10) unsigned NOT NULL,
`field3` decimal(5,2) NOT NULL,
PRIMARY KEY (`field`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
还有解释输出:
id, select_type, table , type , possible_keys, key , key_len, ref , rows, Extra
1 , 'SIMPLE' , 'otherTable' , 'ALL', '' , '' , '' , '' , 294 , ''
1 , 'SIMPLE' , 'hugeCrossingTable', 'ref', 'field1' , 'field1', '4' , 'otherTable.field2', 69 , 'Using where'
【问题讨论】:
-
向我们展示
CREATE TABLE语句和查询的EXPLAIN输出。如果索引正确,但您有非常具体的范围,PARTITIONING该表可能会有所帮助。 -
JOIN 是大表的恶魔。您几乎只想通过索引或主键访问该大小的表。您可以更改表格式以适应查询,甚至可以使用临时内存表吗?这可以使您在查询时间从几分钟到几毫秒。请记住,标准化并不意味着速度。
-
您正在加载所有记录??为什么??存档数据/记录不是一个坏主意(如果您确定不再需要它!)
-
所以你正在基于另一个表中的行子集创建一个新表,例如插入到 target_table (x,y) select x,y from source table ?
-
@Rudie :这都是实时数据。我每 30 分钟运行一次此查询。 @f00:我首先通过其他一些查询获取返回集,看看它们是否与当时需要的匹配,然后将结果放在另一个表中。 @Twisted Pear:关于如何做到这一点的任何建议? @Wrikken:就像我说的,我想把桌子分开,但因为它是一个交叉表,我不知道怎么做!
标签: mysql optimization