web-dev-qa-db-ja.com

インデックスによるMysql結合テーブルの順序

最初のマスターテーブル

CREATE TABLE `edipostingmaster` (
  `ID` bigint(20) NOT NULL AUTO_INCREMENT,
  `applied` int(11) DEFAULT '0',
  `fileName` varchar(255) DEFAULT NULL,
  `checkNo` varchar(100) DEFAULT NULL,
  `checkDate` date DEFAULT NULL,
  `checkCount` int(11) DEFAULT NULL,
  PRIMARY KEY (`ID`),
  UNIQUE KEY `unqiue` (`checkNo`,`fileName`)
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8

最初の詳細表

CREATE TABLE `edipostingclaims` (
  `ID` bigint(20) NOT NULL AUTO_INCREMENT,
  `applied` int(11) DEFAULT '0',
  `fileName` varchar(255) DEFAULT NULL,
  `checkNo` varchar(100) DEFAULT NULL,
  `claimSno` int(11) NOT NULL,
  `claimNo` varchar(100) DEFAULT NULL,
  `claimExists` int(11) DEFAULT NULL,
  PRIMARY KEY (`ID`),
  UNIQUE KEY `UNIQUE` (`fileName`,`checkNo`,`claimSno`)
) ENGINE=InnoDB AUTO_INCREMENT=385 DEFAULT CHARSET=utf8

2番目の詳細表

CREATE TABLE `edipostingcodes` (
  `ID` bigint(20) NOT NULL AUTO_INCREMENT,
  `fileName` varchar(255) DEFAULT NULL,
  `checkNo` varchar(100) DEFAULT NULL,
  `claimSno` int(11) DEFAULT NULL,
  `claimNo` varchar(100) DEFAULT NULL,
  `lineItemNo` int(11) DEFAULT NULL,
  PRIMARY KEY (`ID`),
  KEY `unique` (`checkNo`,`claimSno`,`fileName`,`lineItemNo`)
) ENGINE=InnoDB AUTO_INCREMENT=1289 DEFAULT CHARSET=utf8

これがクエリです

EXPLAIN
SELECT * FROM edipostingmaster a  , edipostingclaims b, edipostingclaims c
WHERE a.fileName = b.fileName AND a.checkNo = b.checkNo
AND b.fileName = c.fileName AND b.checkNo = c.checkNo AND b.claimSno = c.claimSno
AND a.checkNo ='893881996'
ORDER BY b.claimSno

次に、テーブルaのUsing where; Using temporary; Using filesortの表示について説明します。注文がなくても大丈夫です。

3
Senthil Muthiah

この場合、インデックスを使用して(現在の状態ではなく、インデックスの列順序が少し変更された場合)順序付けを高速化できますが、オプティマイザーはフィルタリングを優先するか順序付けを優先するかを決定する必要があります。

おそらく定数_a.checkNo ='893881996'_でフィルタリングし、最初にテーブルaにアクセスすることから始まるため、(インデックスが異なっていても)_b.claimSno_の順序でレコードを取得することは不可能です。

そのため、行検索の最後にソートプロセスが必要であり、それには一時テーブルが必要です。各実行間の時間差が非常に大きくない限り、あまり心配しないでください。

テーブルがディスク上に作成されることになった場合は、そのセッションの_tmp_table_size_と_max_heap_table_size_を調整して、それを回避しようとすることができます-いくつかのvarchar(255)がありますが、それはおそらく悪くなるでしょう、良くはありません。 _sort_merge_passes_の数が非常に多い場合は、そのセッションの_sort_buffer_size_を調整してみてください。

一方、クエリが十分に高速に実行されている場合は、正常な動作であるため、心配する必要はありません。

2
jynus