web-dev-qa-db-ja.com

5.6から5.7にアップグレードした後、MySQL結合のパフォーマンスが大幅に低下する

MySQL 5.6.35からMySQL 5.7.12(AWS RDSで実行)にアップグレードした後、非常に遅くなったかなり単純なクエリがあります。

_SELECT DISTINCT 
  Name,d.id,deviceType,issuedBy, description,avNum,CompanyName,
  BrandName,dwNumber,quant,discDate,Type
FROM table_one d     
JOIN table_two i ON d.id = i.id;
_

5.6では、このクエリは90秒で完了します。 5.7にアップグレードしてから30分以上かかります。各テーブルには約200万行があります。

5.6と5.7の間でオプティマイザ設定を比較することから始めました。

_# 5.6
index_merge=on
index_merge_union=on
index_merge_sort_union=on
index_merge_intersection=on
engine_condition_pushdown=on
index_condition_pushdown=on
mrr=on
mrr_cost_based=on
block_nested_loop=on
batched_key_access=off
materialization=on
semijoin=on
loosescan=on
firstmatch=on
subquery_materialization_cost_based=on
use_index_extensions=on
_
_# 5.7
Optimizer settings in 5.7:
index_merge=on
index_merge_union=on
index_merge_sort_union=on
index_merge_intersection=on
engine_condition_pushdown=on
index_condition_pushdown=on
mrr=on
mrr_cost_based=on
block_nested_loop=on
batched_key_access=off
materialization=on
semijoin=on
loosescan=on
firstmatch=on
subquery_materialization_cost_based=on
use_index_extensions=on
condition_fanout_filter=on
derived_merge=on
duplicateweedout=on
_

私が目にする唯一の変更は、5.7の最後の3つのオプションでした。私は次のようにそれらをオフに切り替えました:

_SET optimizer_switch='condition_fanout_filter=off';
SET optimizer_switch='derived_merge=off';
SET optimizer_switch='duplicateweedout=off';
_

これは効果がありませんでした。次に、innodb設定の違いを調べました(私の5.7インスタンスにはより多くのメモリがあるため、プールサイズの違いがあります)。

_# my innodb changes 5.6 -> 5.7
innodb_adaptive_hash_index_parts added in 5.7, set to ‘8’
innodb_additional_mem_pool_size set to 8388608 in 5.6, removed in 5.7
innodb_buffer_pool_dump_at_shutdown changed from ‘OFF’ to ‘ON’
innodb_buffer_pool_dump_pct added in 5.7, set to ’25’
innodb_buffer_pool_load_at_startup changed from ‘OFF’ to ‘ON’
innodb_buffer_pool_size changed from 2,804,940,800 to 11,811,160,064
innodb_checksum_algorithm changed from ‘innodb’ to ‘crc32’
innodb_deadlock_detect added in 5.7, set to ‘ON’
innodb_default_row_format added in 5.7, set to ‘dynamic’
innodb_file_format changed from ‘Antelope’ to ‘Barracuda’
innodb_file_format_max changed from ‘Antelope’ to ‘Barracuda’
innodb_fill_factor added in 5.7 set to ‘100’
innodb_flush_sync added in 5.7 set to ‘ON’
innodb_log_checksums added in 5.7 set to ‘ON’
innodb_log_write_ahead_size added in 5.7 set to 8192
innodb_max_undo_log_size added in 5.7 set to 1,073,741,824
innodb_mirrored_log_groups removed in 5.7, set to ‘1’ in 5.6
innodb_numa_interleave added in 5.7 set to ‘OFF’
innodb_page_cleaners added in 5.7 set to ‘4’
innodb_purge_rseg_truncate_frequency added in 5.7 set to ‘128’
innodb_strict_mode changed from ‘OFF’ to ‘ON’
innodb_temp_data_file_path added in 5.7, set to 'ibtmp1:12M:autoextend'
innodb_undo_log_truncate added in 5.7, set to ‘OFF’
_

リファレンスマニュアル を確認し、次のスイッチをオフにしようとしました。

_innodb_strict_mode=‘OFF’
innodb_deadlock_detect=‘OFF’
innodb_flush_sync=‘OFF’
innodb_log_checksums=‘OFF’
_

また、影響はありません。

誰かがここで何が起こっているのか教えてもらえるといいのですが。クエリはより大きなワークフローの一部であり、結果として使用できなくなりました。できれば5.6の動作を取り戻したいのですが、DBAの知識が限られているため、試すことが不足しています。誰かが私を正しい方向に向けたり、調査するための追加の道をくれたりすることを願っています。

以下は私のテーブルです。列の多くは幅が広く、データソースがクリーンではないため(ソースを制御できません)、ほとんどの列はVARCHAR(X) DEFAULT NULLとして定義されています。 utf8データが必要ですが、遅いクエリのトラブルシューティングを行う際にlatin1を使用しているため、速度低下の原因として考えられます。 (5.6から5.7への移行が必要な理由は、5.7のインデックスサイズが大きいためです。これにより、大きなUTF8列サイズに対応できます)。

(また、idフィールドはソースデータから取得され、可変幅(最大30文字まで)の英数字の長い文字列であるため、VARCHARにする必要があることも指摘しておく必要があります。 )。

_CREATE TABLE `table_one` (
  `id` varchar(200) NOT NULL DEFAULT '',
  `RecordKey` varchar(50) DEFAULT NULL,
  `VersionStat` varchar(200) DEFAULT NULL,
  `Status` varchar(200) DEFAULT NULL,
  `VersionNumber` varchar(50) DEFAULT NULL,
  `VersionDate` varchar(20) DEFAULT NULL,
  `PublishDate` varchar(20) DEFAULT NULL,
  `DistStart` varchar(20) DEFAULT NULL,
  `DistCommStat` varchar(2000) DEFAULT NULL,
  `BrandName` varchar(100) DEFAULT NULL,
  `VersionModelNumber` varchar(100) DEFAULT NULL,
  `Catalog` varchar(100) DEFAULT NULL,
  `dwNumber` varchar(100) DEFAULT NULL,
  `CompanyName` varchar(500) DEFAULT NULL,
  `DeviceCount` varchar(200) DEFAULT NULL,
  `description` varchar(3000) DEFAULT NULL,
  `Exemption` varchar(1100) DEFAULT NULL,
  `PreMarket` varchar(1500) DEFAULT NULL,
  `DevDRMT` varchar(1000) DEFAULT NULL,
  `DTKit` varchar(200) DEFAULT NULL,
  `Combination` varchar(250) DEFAULT NULL,
  `Usage` varchar(500) DEFAULT NULL,
  `SingleBatch` varchar(50) DEFAULT NULL,
  `SerialNumber` varchar(250) DEFAULT NULL,
  `ManuDate` varchar(20) DEFAULT NULL,
  `ExpDate` varchar(20) DEFAULT NULL,
  `Donation` varchar(50) DEFAULT NULL,
  `LabeldWithMLO` varchar(50) DEFAULT NULL,
  `NLabledMLO` varchar(50) DEFAULT NULL,
  `MLOStatus` varchar(1000) DEFAULT NULL,
  `BTT` varchar(50) DEFAULT NULL,
  `OPP` varchar(50) DEFAULT NULL,
  `BRC` varchar(50) DEFAULT NULL,
  `PriorUse` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
_
_CREATE TABLE `table_two` (
  `id` varchar(200) DEFAULT NULL,
  `Name` varchar(200) DEFAULT NULL,
  `deviceType` varchar(50) DEFAULT NULL,
  `issuedBy` varchar(200) DEFAULT NULL,
  `avNum` varchar(50) DEFAULT NULL,
  `quant` varchar(50) DEFAULT NULL,
  `discDate` varchar(50) DEFAULT NULL,
  `PkgStatus` varchar(50) DEFAULT NULL,
  `Type` varchar(50) DEFAULT NULL,
  KEY `idx_table_two_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
_

EXPLAINも2つで同じです。

_explain extended SELECT DISTINCT ...

******************** 1. row *********************
           id: 1
  select_type: SIMPLE
        table: d
         type: ALL
possible_keys: PRIMARY
          key: 
      key_len: 
          ref: 
         rows: 1596593
     filtered: 100.00
        Extra: Using temporary
******************** 2. row *********************
           id: 1
  select_type: SIMPLE
        table: i
         type: ref
possible_keys: idx_table_two_id
          key: idx_table_two_id
      key_len: 203
          ref: mydb.d.id
         rows: 1
     filtered: 100.00
        Extra: 
_

更新#1:

ここにいくつかの詳細があります。両方のサーバーでパフォーマンススキーマを有効にしました。 5.7サーバーは多くの_hash_table_locks_を表示します:

_SELECT EVENT_NAME, COUNT_STAR
       FROM performance_schema.events_waits_summary_global_by_event_name
       ORDER BY COUNT_STAR DESC LIMIT 10;


# EVENT_NAME, COUNT_STAR
'wait/synch/sxlock/innodb/hash_table_locks',   '3256808433'
'wait/synch/mutex/innodb/buf_pool_mutex',      '19266748'
'wait/synch/mutex/innodb/log_sys_mutex',       '14488781'
'wait/io/table/sql/handler',                   '13676918'
'wait/synch/mutex/innodb/lock_mutex',          '11431841'
...
_

さらに、おそらく_wait/io/table/sql/handler_が原因で、_hash_table_locks_に多くの時間が費やされていることがわかります。それらは、時間の上位2つの消費者(ピコ秒)です。

_SELECT EVENT_NAME, SUM_TIMER_WAIT
       FROM performance_schema.events_waits_summary_global_by_event_name where event_name != "idle"
       ORDER BY SUM_TIMER_WAIT DESC LIMIT 10;

# EVENT_NAME, SUM_TIMER_WAIT
'wait/io/table/sql/handler',                 '1300909619487480' # 1300s
'wait/synch/sxlock/innodb/hash_table_locks', '98099101074540'   # 98s
'wait/io/file/innodb/innodb_data_file',      '5035505718525'
'wait/io/socket/sql/client_connection',      '344937541275'
'wait/synch/mutex/innodb/fil_system_mutex',  '198749837865'
...
_

これを5.6サーバーで繰り返すと、_hash_table_locks_がこのように時間を消費することはありません。

UPDATE#2:

ディスクがボトルネックになっているかどうかを確認するために、次のことを行いました。

2つの同一のEC2インスタンスをインストールしました。どちらもi3.large(2 vCPU/15.25 GB RAM)と1x425 GB SSDディスクです。最初のインスタンスでは、MySQL 5.7.25をインストールしました。 2番目のインスタンスでは、MariaDB 10.2.21をインストールしました。私は両方のボックス構成をそのままにしました。 MySQLのクエリはまだ30分かかりますが、MariaDBインスタンスは30秒しかかかりません! InnoDBのバージョンはほぼ同じです。MySQLは5.7.25を実行しており、MariaDBは5.7.24を実行しています。これは、Innodbやディスクの制限ではなく、MySQL内の構成の問題であるように思えます。

別の更新:MariaDBインスタンス内では、EXPLAINが少し異なります。 「whereを使用する」句があり、表が逆になっています。 STRAIGHT_JOINを使用してテーブルの順序を変更しようとしましたが、何も変更されませんでした。

_# MariaDB
EXPLAIN SELECT SQL_NO_CACHE DISTINCT
  Name,d.id,deviceType,issuedBy, description,avNum,CompanyName,
  BrandName,dwNumber,quant,discDate,Type
FROM table_one d    
JOIN table_two i ON d.id = i.id;


******************** 1. row *********************
           id: 1
  select_type: SIMPLE
        table: i
         type: ALL
possible_keys: idx_table_two_id
          key:
      key_len:
          ref:
         rows: 2496908
        Extra: Using where; Using temporary
******************** 2. row *********************
           id: 1
  select_type: SIMPLE
        table: d
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 202
          ref: mydb.i.id
         rows: 1
        Extra:
2 rows in set
_

以下にウィルソンが提案した変更を適用しましたが、問題は解決していません。

UPDATE#3:

重要なものを見つけました。 5.6および5.7サーバーでクエリトレーサーを有効にしました。ここに出力を添付しました:

5.6: https://Pastebin.com/KSTeTDdy

5.7: https://Pastebin.com/3SaXNdC

最後に、一時テーブルの作成方法が異なることに気付きました。

_# 5.6
{
  "converting_tmp_table_to_myisam": {
    "cause": "memory_table_size_exceeded",
    "tmp_table_info": {
      "table": "intermediate_tmp_table",
      "row_length": 4570,
      "key_length": 4585,
      "unique_constraint": true,
      "location": "disk (MyISAM)",
      "record_format": "packed"
    }
  }
}
_
_# 5.7
{
  "converting_tmp_table_to_ondisk": {
    "cause": "memory_table_size_exceeded",
    "tmp_table_info": {
      "table": "intermediate_tmp_table",
      "row_length": 4575,
      "key_length": 8,
      "unique_constraint": true,
      "location": "disk (InnoDB)",
      "record_format": "packed"
    }
  }
}
_

5.6はtmpテーブルにMyISAMを使用しており、5.7はInnoDBを使用しています。 たぶんこれが、5.7で_wait/synch/sxlock/innodb/hash_table_locks_が非常に多く発生する理由です。これはInnoDBの行レベルのロックと関係があるのでしょうか?問題は、テストするために古い動作を復元することは可能ですか?

_internal_tmp_disk_storage_engine_を見つけて、5.7サーバーでMyISAMに変更しました。それでも問題は解決しません。/tmpの下に作成されている一時テーブルを確認できます。

_# ls -ltrh /tmp
-rw-rw---- 1 mysql mysql  56K Apr 26 02:27 #sql_f55_0.MAI
-rw-rw---- 1 mysql mysql 368M Apr 26 02:27 #sql_f55_0.MAD
_

今は間違いなくMyISAMを使用していますが、クエリはまだ遅いです。すべてのサーバー(5.7、5.6、およびMariaDB)で、このファイルサイズが368Mになり、それ以上大きくならないことに気づきました。 5.6(<1MB /秒)と比較して、5.6/MariaDB(〜10-15 MB /秒)では、ファイルの成長がはるかに速くなります。

4
blindsnowmobile

変数とグローバルステータスの分析:
(悲しいかな、質問の説明としてここに飛び出すものはありません)

FORCE INDEXなどを行うのは嫌いですが、STRAIGHT_JOINが2つのテーブルの順序付けを強制する最も簡単で安全な方法かもしれません。

所見:

  • バージョン:5.7.25-log
  • 15.25 GBのRAM
  • 稼働時間= 14:05:48;一部のGLOBAL STATUS値は、まだ意味がない場合があります。
  • Windowsで実行していません。
  • 64ビットバージョンの実行
  • 完全に(またはほとんど)InnoDBを実行しているようです。

より重要な問題:

SSDを使用して、これらを変更します。

innodb_flush_neighbors = 0-1からinnodb_io_capacity = 800-200から

データセットのサイズはinnodb_buffer_pool_sizeよりかなり小さいようです。だから、多分あなたは必要以上にRAMを払っていますか?成長の準備をしているなら、このコメントを無視してください。

まれな例外を除いて、innodb_deadlock_detectをオフにするべきではないと思います。

多くのパフォーマンスの低いクエリ。 long_query_timeを下げて、slowlogを利用します。 http://mysql.rjweb.org/doc.php/mysql_analysis#slow_queries_and_slowlog

必要な接続は11だけなので、max_connectionsを40に下げます。これにより、RAMへの特定のプレッシャーが回避されます。

READ-UNCOMMITTEDをよろしいですか?

詳細およびその他の観察:

( Table_open_cache_misses / (Table_open_cache_hits + Table_open_cache_misses) ) = 272 / (6879 + 272) = 3.8%-table_open_cacheの有効性。 -table_open_cacheを増やし、table_open_cache_instancesを確認します。

( innodb_lru_scan_depth * innodb_page_cleaners ) = 1,024 * 4 = 4,096-1秒あたりのページクリーナーの作業量。 -「InnoDB:page_cleaner:1000ms意図したループにかかった...」lru_scan_depthを下げることで修正できる場合があります:1000/innodb_page_cleanersを検討してください

( innodb_page_cleaners / innodb_buffer_pool_instances ) = 4 / 8 = 0.5-innodb_page_cleaners-innodb_page_cleanersをinnodb_buffer_pool_instancesに設定することをお勧めします

( innodb_lru_scan_depth ) = 1,024-「InnoDB:page_cleaner:1000ms意図したループにかかった...」は、lru_scan_depthを下げることで修正できます

( Innodb_buffer_pool_pages_free / Innodb_buffer_pool_pages_total ) = 494,639 / 720896 = 68.6%-現在使用されていないbuffer_poolの割合-innodb_buffer_pool_sizeが必要以上に大きいですか?

( Innodb_buffer_pool_bytes_data / innodb_buffer_pool_size ) = 3,590,832,128 / 11264M = 30.4%-データが使用するバッファプールの割合-小さな割合は、buffer_poolが不必要に大きいことを示している可能性があります

( Uptime / 60 * innodb_log_file_size / Innodb_os_log_written ) = 50,748 / 60 * 128M / 2513408 = 45,166-InnoDBログローテーション間の分5.6.8以降、これは動的に変更できます。 my.cnfも必ず変更してください。 -(ローテーション間の60分の推奨はやや恣意的です。)innodb_log_file_sizeを調整します。 (AWSでは変更できません。)

( innodb_flush_neighbors ) = 1-ブロックをディスクに書き込む際のマイナーな最適化。 -SSDドライブには0を使用します。 HDDの場合は1。

( innodb_io_capacity ) = 200-ディスクで実行可能な1秒あたりのI/Oオペレーション。遅いドライブの場合は100。ドライブを回転させる場合は200。 SSDの場合は1000〜2000。 RAID係数を掛けます。

( innodb_thread_concurrency ) = 0-0 = InnoDBにconcurrency_ticketsに最適なものを決定させます。 -0または64に設定します。これにより、CPUが削減される場合があります。

( innodb_print_all_deadlocks ) = innodb_print_all_deadlocks = OFF-すべてのデッドロックをログに記録するかどうか。 -デッドロックに悩まされている場合は、これをオンにします。注意:デッドロックが多数ある場合、ディスクに大量に書き込まれる可能性があります。

( innodb_deadlock_detect ) = innodb_deadlock_detect = OFF-5.7.15は、デッドロック検出をオフにすることにより、大量の挿入を高速化する方法を提供します-本当にオフにしますか?

( local_infile ) = local_infile = ON-local_infile = ONは潜在的なセキュリティ問題です

( Created_tmp_disk_tables / Questions ) = 37,591 / 73621 = 51.1%-ディスク上のtmpテーブルを必要とするクエリの割合。 -インデックスの向上/ BLOBなし/など.

( Created_tmp_disk_tables / Created_tmp_tables ) = 37,591 / 46560 = 80.7%-ディスクに流出した一時テーブルの割合-tmp_table_sizeとmax_heap_table_sizeを増やす可能性があります。インデックスを改善する;ブロブなどを避ける.

( (Com_insert + Com_update + Com_delete + Com_replace) / Com_commit ) = (168 + 0 + 2 + 0) / 170 = 1-コミットごとのステートメント(すべてのInnoDBを想定)-低:トランザクションでクエリをグループ化するのに役立つ場合があります。高:長いトランザクションはさまざまなことに負担をかけます。

( Select_scan ) = 51,492 / 50748 = 1 /sec-テーブル全体のスキャン-インデックスを追加する/クエリを最適化する(小さなテーブルでない限り)

( Select_scan / Com_select ) = 51,492 / 71543 = 72.0%-全テーブルスキャンを実行する選択の%。 (ストアドルーチンにだまされる可能性があります。)-インデックスを追加する/クエリを最適化する

( ( Com_stmt_prepare - Com_stmt_close ) / ( Com_stmt_prepare + Com_stmt_close ) ) = ( 2 - 0 ) / ( 2 + 0 ) = 100.0%-あなたですか( binlog_format ) = binlog_format = MIXED-STATEMENT/ROW/MIXED。 ROWが推奨されます。デフォルトになる場合があります。

( expire_logs_days ) = 0-binlogを自動的にパージするまでの時間(この日数が経過した後)-大きすぎる(またはゼロ)=ディスク領域を消費します。小さすぎる=ネットワーク/マシンのクラッシュに迅速に対応する必要がある.

( slow_query_log ) = slow_query_log = OFF-遅いクエリをログに記録するかどうか。 (5.1.12)

( long_query_time ) = 10-「遅い」クエリを定義するためのカットオフ(秒)。 -提案2

( Threads_created / Connections ) = 11 / 197 = 5.6%-プロセス作成の迅速性-thread_cache_sizeを増やす(Windows以外)

( thread_cache_size / max_connections ) = 21 / 1320 = 1.6%-(Windowsの場合は0)

( thread_cache_size / Max_used_connections ) = 21 / 11 = 190.9%-スレッドキャッシュを予想される接続数よりも大きくしても、利点はありません。スペースの浪費は不利です。

クエリキャッシュが半分オフになります。 query_cache_type = OFFとquery_cache_size = 0の両方を設定する必要があります。 (噂によると)QCコードに「バグ」があり、両方の設定をオフにしない限り、一部のコードはオンのままになります。

異常に小さい:

Com_set_option = 6.7 /HR
Handler_read_rnd = 0.85 /HR
Innodb_dblwr_pages_written / Innodb_dblwr_writes = 1.05
Select_range = 0
Select_range / Com_select = 0
Sort_rows = 0.85 /HR
Table_locks_immediate = 0.03 /sec
Table_open_cache_hits = 0.14 /sec

異常に大きい:

(Com_select + Qcache_hits) / (Com_insert + Com_update + Com_delete + Com_replace) = 420
Com_alter_user = 0.071 /HR
Com_flush = 12 /HR
Com_purge = 12 /HR
Com_release_savepoint = 0.071 /HR
Com_savepoint = 0.071 /HR
Handler_read_next / Handler_read_key = 145
Handler_read_rnd_next / Handler_read_rnd = 2.43e+6
Handler_savepoint = 0.071 /HR
Handler_savepoint_rollback = 0.28 /HR
Innodb_buffer_pool_pages_flushed / max(Questions, Queries) = 1.24
Performance_schema_file_instances_lost = 2

異常な文字列:

ft_boolean_syntax = + -><()~*:&
gtid_mode = OFF_PERMISSIVE
have_ssl = YES
innodb_fast_shutdown = 1
innodb_flush_sync = OFF
innodb_log_checksums = OFF
log_output = TABLE
log_statements_unsafe_for_binlog = OFF
optimizer_trace = enabled=off,one_line=off
optimizer_trace_features = greedy_search=on, range_optimizer=on, dynamic_range=on, repeated_subselect=on
relay_log_recovery = ON
session_track_system_variables = time_zone, autocommit, character_set_client, character_set_results, character_set_connection
time_zone = UTC
transaction_isolation = READ-UNCOMMITTED
tx_isolation = READ-UNCOMMITTED
2
Rick James

RAM innodbバッファープールサイズが2Gから11Gに増加したため、合計の70%まで増加しましたRAM私には問題ないようです。

実行計画とDB構成は同じに見えるため、ハードウェア構成を調べることができます。ハードウェア側から2つのことを確認します。

  1. 以前と現在のCPUクロック速度の比較
  2. マシンの以前および現在のディスクカテゴリ(書き込み/読み取り機能)、および使用しているディスクストライピングがある場合。

安全のために、テーブルをレイアウトしてください。テーブルサイズが小さい場合は、これを最適化して断片化を削除することもできます。断片化レポートを取得するには、データベースで mysqltuner ツールを実行します。

お役に立てれば。

ありがとう、サンジーバ

1

テーブルを分析すると、どちらもフィールドIDに一意の識別子を使用するので、distinct句は不要であり(コストがかかります)、自由に削除できます。

次のようにtable_onetable_twoを交換して、クエリ内のテーブルの順序を変更します。

SELECT Name,d.id,deviceType,issuedBy, description,avNum,CompanyName,   
BrandName,dwNumber,quant,discDate,Type
FROM table_two d 
JOIN table_one i 
ON d.id = i.id;

これを実行したら、Explainクエリを実行すると、extraセクションに次のように表示されます。Using where、noより長い(distinctを削除した後)temporaryを使用します。

私のMySQL 5.6.43ボックスに、この結果が表示されます。

    explain SELECT d.Name,d.id,d.deviceType,d.issuedBy, i.description,d.avNum,i.CompanyName,    
i.BrandName,i.dwNumber,d.quant,d.discDate,d.Type
 FROM table_one i inner  JOIN table_two d 
ON d.id = i.id;
+----+-------------+-------+------+------------------+------------------+---------+----------+------+-------+
| id | select_type | table | type | possible_keys    | key              | key_len | ref      | rows | Extra |
+----+-------------+-------+------+------------------+------------------+---------+----------+------+-------+
|  1 | SIMPLE      | i     | ALL  | PRIMARY          | NULL             | NULL    | NULL     |    1 | NULL  |
|  1 | SIMPLE      | d     | ref  | idx_table_two_id | idx_table_two_id | 203     | upc.i.id |    1 | NULL  |
+----+-------------+-------+------+------------------+------------------+---------+----------+------+-------+



explain SELECT d.Name,d.id,d.deviceType,d.issuedBy, i.description,d.avNum,i.CompanyName,    i.BrandName,i.dwNumber,d.quant,d.discDate,d.Type 
FROM table_two d inner  JOIN table_one i 
ON d.id = i.id;

+----+-------------+-------+--------+------------------+---------+---------+----------+------+-------------+
| id | select_type | table | type   | possible_keys    | key     | key_len | ref      | rows | Extra       |
+----+-------------+-------+--------+------------------+---------+---------+----------+------+-------------+
|  1 | SIMPLE      | d     | ALL    | idx_table_two_id | NULL    | NULL    | NULL     |    1 | Using where |
|  1 | SIMPLE      | i     | eq_ref | PRIMARY          | PRIMARY | 202     | upc.d.id |    1 | NULL        |
+----+-------------+-------+--------+------------------+---------+---------+----------+------+-------------+

私が入力したとおりに説明コマンドを実行して、私と同じ結果が得られるかどうか教えてください。

また、区別なしでクエリを実行してみて、パフォーマンスが大幅に向上するかどうかを確認してください。

2019年4月21日、ypercubeは、table_twoにPRIMARY KEYがなく、UNIQUEの指定がないことを指摘しました。以下を考慮してください。

CREATE TABLE `table_two` (
`aincid` INT AUTO_INCREMENT PRIMARY KEY,
`id` varchar(200) NOT NULL DEFAULT 'idUNKNOWN',
`Name` varchar(200) DEFAULT NULL,
`deviceType` varchar(50) DEFAULT NULL,
`issuedBy` varchar(200) DEFAULT NULL,
`avNum` varchar(50) DEFAULT NULL,
`quant` varchar(50) DEFAULT NULL,
`discDate` varchar(50) DEFAULT NULL,
`PkgStatus` varchar(50) DEFAULT NULL,
`Type` varchar(50) DEFAULT NULL,
KEY `idx_table_two_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

次にEXPLAIN SELECT SQL_NO_CACHE ......の結果を投稿してください。

1
Wilson Hauck

1秒あたりのレート= 5.7インスタンス[mysqld]セクションで考慮すべきRPSの提案、

innodb_lru_scan_depth=100  # from 1024 to conserve 90% of CPU cycles for the function
innodb_io_capacity=1900  # from 200 to allow higher IOPS on your SSD
innodb_flushing_avg_loops=5  # from 30 to reduce innodb_buffer_pool_pages_dirty of 26
read_buffer_size=512K  # from 256K to reduce handler_read_next RPS of 47,391
read_rnd_buffer_size=256K  # from 512K to reduce handler_read_rnd_next RPS of 574

免責事項:私は自分のプロファイル、ネットワークプロファイルで言及されているWebサイトのコンテンツ作成者であり、追加の提案と無料のユーティリティスクリプトを利用できます。

0
Wilson Hauck

プロセスリストまたはプロファイラーを使用してスタックしている状態クエリを確認できますか?

試してください:

mysql> SET SESSION profiling = 1; 
mysql> <<EXECUTE YOUR QUERY >>;
mysql> SHOW PROFILES;
mysql> SHOW PROFILE FOR << Query Id >>;

クエリがstatistics状態のままである場合は、optimizer-search-depth=#パラメータを探す必要があります。

これが役立つことを願っています。

0
JYOTI RAJAI