管理できないデータベースに接続しており、2 つのテーブル (小さいテーブルと数桁大きいテーブル) の間で左結合を行うクエリを作成しました。ある時点で、データベースから次のエラーが返されました。
テーブル '/tmp/#sql_some_table.MYI' のキー ファイルが正しくありません。修復してみてください
管理者に連絡したところ、このエラーが発生するのは、左結合を正しく行っていないためであると言われました。小さなテーブルを大きなテーブルに結合したままにしないでください。結合順序を逆にする必要があります。彼らが与えた理由は、私のやり方でやると、MySQL が大きすぎる一時テーブルを作成しようとし、クエリが失敗するからです。彼らのソリューションは他の場所では失敗しますが、ここでは重要ではありません。
私は彼らの説明が奇妙だと思ったので、クエリで説明を実行しました:
id = '1'
select_type = 'SIMPLE'
table = 'small_table'
type = 'ALL'
possible_keys = NULL
key = NULL
key_len = NULL
ref = NULL
rows = '23'
Extra = 'Using temporary; Using filesort'
id = '1'
select_type = 'SIMPLE'
table = 'large_table'
type = 'ref'
possible_keys = 'ID,More'
key = 'ID'
key_len = '4'
ref = 'their_db.small_table.ID'
rows = '41983'
Extra = NULL
(2 番目のテーブルの 41983 行は、私にとってはあまり興味深いものではありません。最新のレコードが必要だっただけです。これが、クエリがorder by large_table.ValueDateTime desc limit 1
最後にある理由です。)
管理者自身が私に言った、一意の値を保持する必要がある(したがって、インデックスが付けられていると想定した)列による選択を行うように十分に注意しましたが、それらの列にインデックスを付けていないようです。
私の質問は - 私が行った方法で結合を行っていますか ('small_table LEFT JOIN large_table') 一般的に悪い習慣ですか、それとも適切なインデックス作成でそのようなクエリを正常に実行できますか?
編集:クエリは次のようになります(これは実際のクエリではありませんが、似ています):
select large_table.ValueDateTime as LastDate,
small_table.DeviceIMEI as IMEI,
small_table.Other_Columns as My_Names,
large_table.Pwr as Voltage,
large_table.Temp as Temperature
from small_table left join large_table on small_table.ID = large_table.ID
where DeviceIMEI = 500
order by ValueDateTime desc
limit 1;
基本的に私がやっていることは、電圧と温度が時間の経過とともに変化することを考えると、デバイスの最新のデータを取得しようとすることです。DeviceIMEI、ID、および ValueDateTime は一意である必要がありますが、インデックスが作成されていません (前に述べたように、私はデータベースを管理しておらず、読み取りアクセス許可しか持っていません)。
編集2:
元のクエリを書き直そうとするのではなく、実際の質問に答えることに集中してください。