MySQL查询与SELECT一样快速,挂起在INSERT上。。。选择或创建表格。。。挑选
这里真是让人头疼。以下是我的两个测试表来说明:MySQL查询与SELECT一样快速,挂起在INSERT上。。。选择或创建表格。。。挑选,mysql,Mysql,这里真是让人头疼。以下是我的两个测试表来说明: CREATE TABLE IF NOT EXISTS `atest` ( `id` int(10) unsigned NOT NULL DEFAULT '0', `testval` double DEFAULT NULL, PRIMARY KEY (`id`), KEY `testval` (`testval`) ) ENGINE=MyISAM DEFAULT CHARSET=UTF8; CREATE TABLE IF NOT E
CREATE TABLE IF NOT EXISTS `atest` (
`id` int(10) unsigned NOT NULL DEFAULT '0',
`testval` double DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `testval` (`testval`)
) ENGINE=MyISAM DEFAULT CHARSET=UTF8;
CREATE TABLE IF NOT EXISTS `atestb` (
`id` bigint(16) NOT NULL DEFAULT '0',
`lookup` bigint(16) NOT NULL,
PRIMARY KEY (`id`),
KEY `lookup` (`lookup`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
表中的记录太多,无法将数据值粘贴到此处,但您可以在此处下载包含数据的表:
我的问题是:我必须在atestb.lookup中找到大于或等于atest.testval中每个记录的值的第一个记录
在尝试了几种不同的方法后,得出此结果的最快方法是:
SELECT a.id, a.testval,
(SELECT lookup
FROM atestb
WHERE lookup >= a.testval
ORDER BY lookup LIMIT 1)
AS closest
FROM atest a
因此,这工作得又快又好。但是问题是,我需要使用这个查询来创建一个新表。在本例中,这是一个临时表,但我用一个永久表进行了尝试,得到了相同的结果。如果我跑步:
CREATE TEMPORARY TABLE tmptbl
SELECT a.id, a.testval,
(SELECT lookup
FROM atestb
WHERE lookup >= a.testval
ORDER BY lookup LIMIT 1)
AS closest
FROM atest a
它只是无限期地挂在“发送数据…”上,我必须终止这个进程。我还尝试创建表,然后使用INSERT INTO TABL tmptbl表,得到了相同的结果
问题显然出在子查询派生列上,因为如果我不使用该列或替换其他值,它就会工作。如果atest中只有少量记录,但实际表中有45K条记录,那么它也可以工作
如果有另一种不使用子查询的方式进行查询,也可以,但类似于这样:
SELECT a . * , MIN( b.lookup )
FROM `atest` a
LEFT JOIN atestb b ON b.lookup >= a.testval
GROUP BY a.id
。。。由于连接处于>=,因此效率也非常低。所以它也挂了起来。我的子查询工作得很好…但它无法插入到表中
解释的结果(无论是普通选择还是插入…选择都是相同的):
你知道这是怎么回事吗?你能展示一下你查询的解释结果吗?45k行根本没什么大不了的。你可能需要读一下@JorgeCampos是的,这根本没什么,正如我说的,它对于简单的选择很好。我们总是在更大的表上执行更复杂的查询。该问题仅在尝试插入语句或从语句创建表时发生。我已经添加了EXPLAIN的输出-无论是普通选择还是插入都是一样的。。。选择:
id | select_type |table |type | possible_keys | key | key_len | ref | rows | Extra
-------------------------------------------------------------------------------------------------------------------------------------
1 | PRIMARY | a | ALL | NULL | NULL | NULL | NULL |45886 | NULL
2 | DEPENDENT SUBQUERY | atestb | index | lookup | lookup | 8 | NULL | 1 | Range checked for each record (index map: 0x2); Using index`