我有两个非常相似的查询。他们在相同的四个表上工作,如下所示:
users_old => MyISAM
users_new => InnoDB
test_attempts => InnoDB
tests => MyISAM
基本上,查询是在 test、users_old 和 users_new 上运行的,它们插入到 test_attempts 中。
这是第一个查询,运行大约需要一分钟,这很长,但不是一个严重的问题。它的主要WHERE
子句包含子句:tests.overall_score IS NOT NULL AND
稍后在此查询的第二个版本中进行了更改:
# this query takes everyone that has taken the wsat-pe legacy and gives them an attempt record
INSERT INTO
test_attempts (`user_id`, `test_id`, `score`, `created`, `modified`, `is_deleted`, `meter`, `type`, `status`)
SELECT
users_new.id, 76, tests.overall_score, FROM_UNIXTIME(start_time), FROM_UNIXTIME(end_time), NULL, NULL, 'normal', 'complete'
FROM
users_old, users_new, tests
WHERE
users_old.user_email = users_new.email AND
tests.user_id = users_old.id AND
users_new.role <> 'admin' AND
tests.overall_score IS NOT NULL AND
users_new.id NOT IN (SELECT test_attempts.user_id FROM test_attempts WHERE test_attempts.test_id = 76);
这是第二个查询,运行大概需要十分钟,比较长。它的主要WHERE
子句包含子句:tests.overall_score IS NULL AND
另外,SELECT
标题更改'complete'
为,'canceled'
但这些是唯一的区别。
# This cancels the attempts that have been droped by users
INSERT INTO
tests_attempts (`user_id`, `test_id`, `score`, `created`, `modified`, `is_deleted`, `meter`, `type`, `status`)
SELECT
users_new.id, 76, tests.overall_score, FROM_UNIXTIME(start_time), FROM_UNIXTIME(end_time), NULL, NULL, 'normal', 'canceled'
FROM
users_old, users_new, tests
WHERE
users_old.user_email = users_new.email AND
tests.user_id = users_old.id AND
users_new.role <> 'admin' AND
tests.overall_score IS NULL AND
users_new.id NOT IN (SELECT test_attempts.user_id FROM test_attempts WHERE test_attempts.test_id = 76);
它们一个接一个地在给定的表上运行。我不明白为什么NOT
从第一个查询中删除会导致操作时间增加十倍。在我了解为什么会出现这个时间差之前,我无法在我的生产环境中运行它。由于 MyISAM 表使用表锁定,这会将我们的站点锁定十分钟,这不是一个真正的选择。我不确定为什么会出现这种时间差异,因此任何见解都会有所帮助。谢谢你。