12

さらに処理するために、クエリ結果を一時テーブルに保存しようとしています。

create temporary table tmpTest
(
    a FLOAT,
    b FLOAT,
    c FLOAT
)
engine = memory;

insert into tmpTest
(
    select a,b,c from someTable
    where ...
);

しかし、何らかの理由で挿入には最大 1 分かかりますが、副選択だけでは数秒しかかかりません。データを SQL 管理ツールの出力に出力するのではなく、一時テーブルに書き込むのに時間がかかるのはなぜですか?

UPDATE マイ セットアップ: 8 つの Debian Linux ndb データ ノードを備えた MySQL 7.3.2 クラスター 1 つの SQL ノード (Windows Server 2012)

選択を実行しているテーブルはndbテーブルです。

「insert into ..」を使用すると実行計画が異なるかどうかを調べようとしましたが、同じように見えます:(書式設定について申し訳ありませんが、stackoverflowにはテーブルがありません)

id select_type テーブル タイプ possible_keys キー key_len ref 行 エクストラ
1 プライマリ <subquery3> すべて \N \N \N \N \N \N
1 PRIMARY foo ref PRIMARY PRIMARY 3 <subquery3>.fooId 9747434 where の使用
2 SUBQUERY someTable range PRIMARY PRIMARY 3 \N 136933000 プッシュ条件で where を使用。MRR の使用; 一時的な使用; ファイルソートの使用
3 マテリアライズされた tmpBar すべて \N \N \N \N 1000 \N

CREATE TABLE ... SELECT も遅いです。47 秒 vs. テーブルの挿入/作成なしの 5 秒。

4

3 に答える 3

1

私は同じ問題を経験し、実際にそれを解決したサブクエリをいじっていました。選択に大量の行がある場合、データの挿入に非常に時間がかかります。例:

INSERT INTO b2b_customers (b2b_name, b2b_address, b2b_language)
SELECT customer_name, customer_address, customer_language
FROM customers
WHERE customer_name LIKE "%john%"
ORDER BY customer_created_date DESC
LIMIT 1

LIMIT を INSERT データと組み合わせて使用​​することは、適切なオプションではありません。したがって、データの取得と挿入に 2 つの個別のクエリを使用するか、サブクエリを使用できます。例:

INSERT INTO b2b_customers (b2b_name, b2b_address, b2b_language)
SELECT * FROM (
SELECT customer_name, customer_address, customer_language
FROM customers
WHERE customer_name LIKE "%john%"
ORDER BY customer_created_date DESC
LIMIT 1
) sub1

スクリプトを変更しなくても、これは迅速な解決策になります。

したがって、サブクエリの実行に 0.01 秒、挿入の実行に 60 秒かかる理由がわかりません。制限なしで 1000 件以上の結果が得られます。私の場合、サブクエリによってパフォーマンスが 60 秒から 0.01 秒に向上しました。

于 2016-11-03T09:28:04.757 に答える
0

その理由は、コンピューターの読み取りと書き込みの方法と一時ファイルの動作に関係しています。select はハード ドライブ上のインデックス付きファイルにあるデータを読み取りますが、insert は一時ファイルを使用してそのファイルに書き込みます。より多くの RAM が必要であり、そうするのはより困難です。なぜ1分かかるのか、正確にはわかりませんが、コードが少し間違っているのではないかと思います。

于 2013-10-09T10:36:40.537 に答える