非常によく似た 2 つのクエリがあります。次のように、同じ 4 つのテーブルで動作します。
users_old => MyISAM
users_new => InnoDB
test_attempts => InnoDB
tests => MyISAM
基本的に、クエリは test、users_old、および users_new に対して実行され、test_attempts に挿入されます。
これは最初のクエリです。実行には約 1 分かかります。これは長いですが、深刻な問題ではありません。その主要なWHERE
句には句が含まれています:tests.overall_score IS NOT NULL AND
これは、このクエリの 2 番目のバージョンで後で変更されます。
# 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);
これは 2 番目のクエリです。実行には約 10 分かかり、時間がかかります。その主要な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
最初のクエリから を削除すると、操作時間が 10 倍になる理由がわかりません。この時間差が発生する理由を理解するまで、実稼働環境でこれを実行することはできません。MyISAM テーブルはテーブル ロックを使用しているため、これによりサイトが 10 分間ロックダウンされ、実際にはオプションではありません。今回の不一致が発生している理由がわからないので、洞察があれば役立ちます。ありがとうございました。