0

誰かがこのクエリを最適化するのを手伝ってもらえますか?15秒かかります。WHERE句を結合自体まで移動しても、同じ結果になります。

SELECT
`users`.`employeeID` as `username`,
`users`.`firstName` as `fname`,
`users`.`lastName` as `lname`
FROM `enrollment`
INNER JOIN `users` ON `enrollment`.`employeeID` = `users`.`employeeID`
WHERE `enrollment`.`number` = [int]
AND
`enrollment`.`term` = [int]
AND
(
`enrollment`.`status` = 'E'
OR
`enrollment`.`status` = 'M'
)
ORDER BY    
`users`.`lastName` ASC,
`users`.`firstName` ASC;

これと同じくらい時間がかかります:

SELECT
`users`.`employeeID` as `username`,
`users`.`firstName` as `fname`,
`users`.`lastName` as `lname`
FROM `enrollment`
INNER JOIN
`users` ON `enrollment`.`employeeID` = `users`.`employeeID`
AND
`enrollment`.`number` = [int]
AND
`enrollment`.`term` = [int]
AND
(
`enrollment`.`status` = 'E'
OR
`enrollment`.`status` = 'M'
)
ORDER BY    
`users`.`lastName` ASC,
`users`.`firstName` ASC;

これはEXPLAINの結果です

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  users   ALL PRIMARY NULL    NULL    NULL    52925   Using filesort
1   SIMPLE  enrollment  ref employeeID,number_term  employeeID  9   ezlrn.users.employeeID  2   Using where
4

2 に答える 2

0

EXPLAIN SELECT...(your query)徹底的に答えるには、発行して取得したクエリプランと、すでに配置されているインデックス構造を確認する必要があります。

まだインデックスがない(おそらくインデックスを除くPRIMARY KEY)という仮説で、それが問題です。何かを作成する方法を見てみましょう(おそらくさらに改善可能です)。

SELECT
    `users`.`employeeID` as `username`,
    `users`.`firstName` as `fname`,
    `users`.`lastName` as `lname`
FROM `enrollment`
    INNER JOIN `users` ON `enrollment`.`employeeID` = `users`.`employeeID`
WHERE `enrollment`.`number` = [int]
    AND
    `enrollment`.`term` = [int]
    AND
    (
        `enrollment`.`status` = 'E'
    OR
    `enrollment`.`status` = 'M'
    )
    ORDER BY    
        `users`.`lastName` ASC,
        `users`.`firstName` ASC;

との間にJOIN句がenrollment.employeeIDありusers.employeeIDます。

したがって、必要な最初のいくつかのインデックスはすぐそこにあります。

-- CREATE INDEX enrollment_ndx ON enrollment(employeeID); -- wait on this one
CREATE INDEX users_ndx ON users(employeeID);

次に、このWHERE句には、インデックスを付けるのに役立ついくつかの条件が含まれています。したがって、の最終的なインデックスは次のenrollmentようになります。

CREATE INDEX enrollment_ndx ON enrollment(employeeID, number, term, status);

登録とユーザーのインデックスを作成して、再試行してください(クエリプランの投稿)。

注:enrollment.status IN ('M', 'E')クエリで構文を使用して簡略化することもできます。

于 2012-09-12T19:48:27.443 に答える
0

、、、およびenrollmentを含むテーブルのインデックスが必要です。また、インデックスが必要になります(まだ主キーでない場合は、そうする必要があります)。numbertermstatusemployeeIDemployees

CREATE INDEX idx1 ON enrollment (number, term, status);
CREATE INDEX idx2 ON users (employeeID); // if needed

これにより、mysqlがenrollment最初にテーブルを検索し、次にテーブルに結合するためにインデックスを使用するようになりusersます。

于 2012-09-12T19:56:17.573 に答える