2

次の手順があります。

CREATE PROCEDURE getProjectTeams(IN p_idProject INTEGER)
BEGIN
 SELECT idTeam, name, workersCount, confirmersCount, isConfirm 
 FROM Teams JOIN team_project USING (idTeam)
 WHERE idProject = p_idProject;
END $$

そして、ここCREATE TABLEにテーブルTeamsとのスクリプトがありますteam_project:

CREATE TABLE Teams (
 idTeam INT PRIMARY KEY auto_increment,
 name CHAR(20) NOT NULL UNIQUE,
 isConfirm BOOL DEFAULT 0,
 workersCount SMALLINT DEFAULT 0,
 confirmersCount SMALLINT DEFAULT 0 
) engine = innodb DEFAULT CHARACTER SET=utf8 COLLATE=utf8_polish_ci;

CREATE TABLE team_project (
idTeam INT NOT NULL,
idProject INT NOT NULL,
FOREIGN KEY(idTeam) REFERENCES Teams(idTeam)
    ON DELETE CASCADE
    ON UPDATE CASCADE,
FOREIGN KEY (idProject) REFERENCES Projects(idProject)
    ON DELETE CASCADE
    ON UPDATE CASCADE,
PRIMARY KEY(idTeam, idProject)
) engine = innodb DEFAULT CHARACTER SET=utf8 COLLATE=utf8_polish_ci;

サーバー上に同一のスキーマを持つデータベースはほとんどありませんが、この手順は 1 つのデータベースによって呼び出された場合にのみログに記録されます。これらの他のデータベースによって行われた呼び出しはログに記録されません。クエリが遅いかどうかの問題ではありません (常に約 0.0001 秒かかります)。インデックスを使用していないとログに記録される理由についてです。そんなことがあるものか?

Zagor23 が示唆したように、実行しEXPLAINた結果は次のとおりです。a) 手順が記録されているデータベース:

| id | select_type | table        | type | possible_keys     | key       | key_len | ref   | rows | Extra                          |
|  1 | SIMPLE      | team_project | ref  | PRIMARY,idProject | idProject | 4       | const |    3 | Using index                    |
|  1 | SIMPLE      | Teams        | ALL  | PRIMARY           | NULL      | NULL    | NULL  |    4 | Using where; Using join buffer |

b) 手順が記録されていないデータベース:

| id | select_type | table        | type   | possible_keys     | key       | key_len | ref                              | rows | Extra       |
|  1 | SIMPLE      | team_project | ref    | PRIMARY,idProject | idProject | 4       | const                            |    1 | Using index |
|  1 | SIMPLE      | Teams        | eq_ref | PRIMARY           | PRIMARY   | 4       | ecovbase.team_project.idTeam |    1 |             |

実際には、データは少し異なりますが、それほどではありません。GoodDB (ログに記録されていないもの) には、Teams に 11 行、team_project に 420 行、BadDB (Teams に 4 行、team_project に約 800 行) があります。入札差額ではないようです。その手順をログに記録しないようにする方法はありますか?

4

2 に答える 2

2

@ Zagor23 は、なぜこれが起こるのかを説明しています。あなたのテーブルはおそらくこのデータベースではかなり大きく、適切なインデックスがありません。

私のアドバイスは、テーブルにUNIQUEインデックスを追加することですteam_project(idProject, idTeam)


追加されたEXPLAIN出力の後、ログに記録されたケースでは、MySQL オプティマイザーはテーブルからインデックスを使用する必要のないプランを選択し、そのTeamテーブル全体 (4 行!) をスキャンするだけのようです。テーブルには 4 行しかないため、これはおそらくより高速です。

現在、slow-log にはいくつかのデフォルト設定があり、よく覚えていれば、クエリが完了するまでに 0.0001 秒かかる場合でも、インデックスを使用しないクエリをログに追加します。

このロギングを単に無視するか、低速ログ設定を変更して、インデックスを使用しないクエリを無視することができます。MySQL のドキュメントを参照してください: The Slow Query Log

于 2012-07-05T14:25:43.087 に答える
2

その場合はインデックスを使用するため、ログに記録されていない可能性があります。実行してみてください

EXPLAIN SELECT idTeam, name, workersCount, confirmersCount, isConfirm 
FROM Teams JOIN team_project USING (idTeam)
WHERE idProject = p_idProject;

インデックスを使用すべきではないと思われるデータベースで、実際に使用するかどうかを確認してください。MySql は、使用可能でクエリに適したインデックスがあり、返される結果セットが結果セット全体の最大約 7 ~ 8% である場合、インデックスを使用します。

それは同じだと言いますinformation_schemaが、データがそうでない場合、それが異なる動作の理由になる可能性があります。

于 2012-07-05T14:17:36.837 に答える