15

MySQL (innoDB) 5.0 で深刻な問題が発生しています。

非常に単純な SQL クエリが、非常に予期しないクエリ プランで実行されます。

クエリ:

SELECT 
SQL_NO_CACHE
mbCategory.*

FROM 
MBCategory mbCategory 

INNER JOIN ResourcePermission as rp
    ON rp.primKey = mbCategory.categoryId 

where mbCategory.groupId = 12345 AND mbCategory.parentCategoryId = 0 
limit 20;

MBCategory - 216583 行を含む

ResourcePermission - 3098354 行が含まれます。

MBCategory には複数のインデックスがあります (列の順序はインデックスと同じです):

Primary (categoryId)
A (groupId,parentCategoryId,categoryId)
B (groupId,parentCategoryId)

ResourcePermission には複数のインデックスがあります (列の順序はインデックスと同じです):

Primary - on some column
A (primKey).

クエリ プランを調べると、Mysql はテーブル シーケンスを変更し、最初に ResourcePermission から行を選択してから、MBCategory テーブルに結合し (クレイジーなアイデア)、時間がかかります。そこでSTRAIGHT_JOIN、innodb エンジンに正しいテーブル シーケンスを使用させるように追加しました。

SELECT

STRAIGHT_JOIN SQL_NO_CACHE
mbCategory.*

FROM 
MBCategory
 mbCategory 

INNER JOIN ResourcePermission as rp
    ON rp.primKey = mbCategory.categoryId 

where mbCategory.groupId = 12345 AND mbCategory.parentCategoryId = 0 
limit 20;

しかし、ここで2番目の問題Materialzie:私の意見では、mysqlはindex A (primKey)代わりに結合操作で使用する必要があり、各レコード(インデックスマップ:0x400)の範囲チェックを実行し、再び時間がかかります!Force index は役に立たず、mysql はまだ各レコードに対して Range checked を実行しています。

MBCategory には where 基準を満たす行が 23 行しかなく、結合後は 75 行しかありません。この操作でmysqlに正しいインデックスを選択させるにはどうすればよいですか?

4

2 に答える 2

46

さて、初歩的な問題。私はビールを借りている。私が最近調整しているシステムは、私が開発したシステムではありません。パフォーマンスを改善するために管理職から割り当てられたものです (元のチームはこのトピックに関する知識がありません)。

SQL クエリ、インデックス、アプリケーションによって実行される SQL クエリの数を数週間改善した後、この場合の最も重要なことの 1 つをチェックしませんでした!!

列のタイプが異なります!

ある程度のコードを書いたことのある開発者は、かなり大きな話題になるはずです。

手伝ってくれてありがとう !

于 2012-11-07T08:50:05.610 に答える