質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
InnoDB

InnoDBは、MySQLの規定のストレージエンジンです。信頼性とパフォーマンスが高く、汎用性があります。レコードにロックを掛けられることに加え、ACID互換のトランザクションにも対応しています。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

phpMyAdmin

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

1回答

148閲覧

utf8mb4_binに変更するとインデックスが使われなくなる

SnowCaucasus

総合スコア0

InnoDB

InnoDBは、MySQLの規定のストレージエンジンです。信頼性とパフォーマンスが高く、汎用性があります。レコードにロックを掛けられることに加え、ACID互換のトランザクションにも対応しています。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

phpMyAdmin

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2025/04/23 17:04

実現したいこと

リザルトテーブルとユーザーテーブルがあり、これらのテーブルをユーザーIdで結合したときになぜかこの2つのテーブルをインデックスを使わずに結合しようとしてしまいます。
ユーザーテーブルには主キーがあり、リザルトテーブルにはユーザーIdにインデックスが貼られています。
考えられる原因はなんでしょうか?
これは、リザルトテーブルのユーザーIdの照合順序をutf8mb3_general_ciからutf8mb4_binに変更したときに発生しました。

前提

MySQLで2つのテーブルを実装しました。
1つはユーザーテーブルで、カラムにはユーザーId、ユーザー名があります。主キーはユーザーIdです。
もう1つはリザルトテーブルで、これはゲームのスコアを記録するためのテーブルです。カラムにはId(自動採番)、ユーザーId、スコアがあります。主キーはId、ユーザーIdにインデックスが貼られています。
具体的には、以下のようなテーブル構成になっています。

ユーザーテーブル

名前タイプ照合順序属性Nullデフォルト値コメントその他
ユーザーIdvarchar(30)utf8mb4_binいいえなし
ユーザー名varchar(80)utf8mb4_0900_ai_ciいいえなし

リザルトテーブル

名前タイプ照合順序属性Nullデフォルト値コメントその他
IdintいいえなしAUTO_INCREMENT
ユーザーIdvarchar(30)utf8mb4_binいいえ
スコアintいいえなし

発生している問題・エラーメッセージ

以下のSQLの実行に10秒以上かかってしまう。

SELECT Id, スコア, ユーザー.ユーザー名 FROM リザルト INNER JOIN ユーザー ON リザルト.ユーザーId = ユーザー.ユーザーId ORDER BY Id DESC LIMIT 50

EXPLAINの結果

idselect_typetablepartitionstypepossible_keyskeyskey_lenrefrowsfilteredExtra
1SIMPLEユーザーNULLALLPRIMARYNULLNULLNULL10909100.00Using temporary; Using filesort
1SIMPLEリザルトp0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15refユーザーIdユーザーId122データベース名.ユーザー.ユーザーId38100.00NULL

INNER JOINをなくすと0.0006秒で処理が完了する。

SELECT Id, スコア FROM リザルト ORDER BY Id DESC LIMIT 50

試したこと

2つのテーブルに対してphpMyAdminを用いてテーブルの分析、テーブルをチェックする、テーブルのデフラグ、テーブルを最適化する、を実施しました。
また、リザルトテーブルのユーザーIdの照合順序をutf8mb3_general_ciに戻しても、上記のSQLに10秒以上かかるようになってしまいました。

補足情報

ユーザーテーブルのレコード数は約10,000
リザルトテーブルのレコード数は約4,000,000です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

試した範囲では問題ないですね。
あえて言えば、ユーザーテーブルの主キーにエンコードに依存するようなものを指定するのはトラブルの元ということ。通常はintなどブレがでないものを利用します
場合によっては外部キー制約をつけるとeq_refでインデックスが働きやすくなると思います

投稿2025/04/24 00:53

編集2025/04/24 01:40
yambejp

総合スコア117615

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問