ありがとうございます。私のデータベースをMySQL 5.5から5.7にアップグレードする際に問題が発生しました。私は完全に完全に混乱しています。アップグレードはmysqldumpなどを使用して行われていませんでしたが、複数の非常に長いSQLスクリプトを使用して複数のタブで区切られた入力ファイルから再構築しました。 (ストアドプロシージャ内の)具体的には一つの一見無害なクエリは私に迷惑を与えてきたと私はなぜうまくいかないことができます。SELECTサブクエリを使用するUPDATEは、MySQL 5.7では非常に遅く実行されますが(5.5でも問題ありませんでした)
UPDATE liverpool.master_person mp
SET Link_Count = (SELECT count(*) FROM liverpool.person_record pr
WHERE mp.Master_Person_ID = pr.Master_Person_ID) - 1;
これはかなり単純なようだが、このクエリからEXPLAINは、いくつかの深刻な行走査が起こっていることを示してい上:
# id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra
========================================================================================================================================================================
'1' | 'UPDATE' | 'mp' | NULL | 'index' | NULL | 'PRIMARY' | '4' | NULL | '1198100' | '100.00' | NULL
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'2' | 'DEPENDENT SUBQUERY' | 'pr' | NULL | 'index' | NULL | 'Master_Person_ID_IDX' | '17' | NULL | '1200537' | '100.00' | 'Using where; Using index'
重要なことは、UPDATEのための1198100およびSELECTサブクエリのための1200537である行列、のようです。これらの数値は、両方とも参照先テーブルの両方の合計行数にかなり近くなっています(両方とも1207744)。だから両方の行をスキャンするために完全な行をしているように見えますが、なぜそれは見えません。正確に同じクエリがMySQL 5.5で正常に機能しました。 this解決策が助けになると思っていましたが、 'derived_merge = off'をoptimizer_switchに渡してサーバーを再起動しても役に立たなかったことを期待していました。
私は確かにこのクエリが超高速であるとは思わない。必ずしもそうである必要はありません。以前はスピードが速かったのですが(7200rpm回転ディスクでは数分)、MySQL 5.7へのアップグレード以来、これは宇宙の猛暑の前にいつでも完了しないようです。長いです。誰もそこに誰かがアイデアを持っていますか?クエリの書き換え、my.iniの設定など
また、私が何らかの方法でプロトコルを破っているのか、私が質問を改善できるかどうか、私に知らせてください。私が上で言ったように、それは私の最初の投稿です。
ありがとうございます。
EDIT:this解決策が有望であると私は考えました。明らかに異なる文字セット/照合を持つテーブルは、お互いのインデックスを正しく読み取ることができません。私はかなりすべてがlatin1
にあったことを確信していたが、確かめる価値があると考えた。だから私はCREATE TABLE
ステートメントのすべてに明示的にDEFAULT CHARSET=latin1
を追加し、CHARACTER SET latin1
をLOAD DATA INFILE
ステートメントに追加しました。悲しいことに、変化はありません。
は私が適切にフォーマットされたEXPLAIN親切な人にありがとう! – convensive
Q:\ '' Master_Person_ID' \ '\' 'Master_Person_ID_IDX' \'インデックスの先頭の列ですか?サブクエリがある場合は、サブクエリがかなり速くなると期待しています。このサブクエリは、100万回(外部クエリの各行に対して1回)実行する場合、高速にする必要があります。InnoDBのバッファプールサイズ(これがInnoDBテーブルの場合)が考慮されます。このステートメントを "ステートメント"ベースでログ記録するのか、それともバイナリーログであるのか。また、ロールバックの生成、行ロック取得(他のDML文によるロックによる競合)などもあります。 – spencer7593
@ spencer7593 'liverpool.person_record'テーブルの' Master_Person_ID_IDX'は、 'CREATE INDEX Master_Person_ID_IDX ON liverpool .person_record(Master_Person_ID ASC); '' Master_Person_ID'は、(私が正しくあなたを理解している場合)先行する唯一の列です。 – convensive