私は現在、4.9452秒を実行している重いスクリプト(クエリ)を最適化しようとしています。 PHPのwhileループが返されるものに基づいていくつかの配列を設定しますが、それは別の問題です。MySQLスクリプトの最適化 - 異なるテーブルのユーザー、ユーザーアドレス、国
EDIT - usersテーブルは〜9000行、user_addressテーブルは〜3000行、shop_countries〜200行です。ここで
は私のクエリです:
SELECT
users.id AS user_id,
users.unique_code AS user_unique_code,
users.first_name AS user_first_name,
users.surname AS user_surname,
users.organisation AS user_organisation,
users.telephone AS user_telephone,
users.email AS user_email,
users.password AS user_password,
users.newsletter AS user_newsletter,
user_address.id AS user_address_id,
user_address.user_id AS user_address_user_id,
user_address.nickname AS user_address_nickname,
user_address.address_type AS user_address_type,
user_address.address_line_1 AS user_address_line_1,
user_address.address_line_2 AS user_address_line_2,
user_address.address_line_3 AS user_address_line_3,
user_address.city AS user_address_city,
user_address.postcode AS user_address_postcode,
user_address.country_id AS user_address_country_id,
shop_countries.printable_name
FROM users
LEFT JOIN user_address ON users.id = user_address.user_id
LEFT JOIN shop_countries ON shop_countries.id = user_address.country_id
WHERE (users.surname != "" OR users.first_name != "")
ORDER BY users.surname ASC, users.first_name ASC;
私は、彼らがそれらに割り当てられたアドレスを持っている場合に関係なく、すべてのユーザーを選択し、[が利用可能アドレスがある場合、どの国を添付する必要があります。ここで
の結果は、EXTENDED
をEXPLAINされたこれまでのところ、私がちょうどJOIN
にLEFT JOIN
を変更した場合、クエリは1秒未満で実行されるようです。問題がある場合は、アドレスを持っているかどうかにかかわらず、すべてのユーザーが必要です。
PHPスクリプト
私の設計上の参考のため、対応するPHP関数を参照してくださいしたい人のために、下記を参照してください。
function getAllUsersWithAddresses() {
$customers = array();
$sql = 'SELECT
users.id AS user_id,
users.unique_code AS user_unique_code,
users.first_name AS user_first_name,
users.surname AS user_surname,
users.organisation AS user_organisation,
users.telephone AS user_telephone,
users.email AS user_email,
users.password AS user_password,
users.newsletter AS user_newsletter,
user_address.id AS user_address_id,
user_address.user_id AS user_address_user_id,
user_address.nickname AS user_address_nickname,
user_address.address_type AS user_address_type,
user_address.address_line_1 AS user_address_line_1,
user_address.address_line_2 AS user_address_line_2,
user_address.address_line_3 AS user_address_line_3,
user_address.city AS user_address_city,
user_address.postcode AS user_address_postcode,
user_address.country_id AS user_address_country_id,
shop_countries.printable_name
FROM users
LEFT JOIN user_address ON users.id = user_address.user_id LEFT JOIN shop_countries ON shop_countries.id = user_address.country_id WHERE (users.surname != "" OR users.first_name != "") ORDER BY users.surname ASC, users.first_name ASC;';
$users_query = mysql_query($sql);
$customers = array();
while($row = getData($users_query)) {
if(!isset($customers[$row['user_id']])) {
$customers[$row['user_id']] = array(
'id' => $row['user_id'],
'unique_code' => $row['user_unique_code'],
'first_name' => $row['user_first_name'],
'surname' => $row['user_surname'],
'organisation' => $row['user_organisation'],
'telephone' => $row['user_telephone'],
'email' => $row['user_email'],
'password' => $row['user_password'],
'newsletter' => $row['user_newsletter']
);
}
if(isset($customers[$row['user_id']]) && !empty($row['user_address_type'])) {
$customers[$row['user_id']]['addresses'][$row['user_address_type']][] = array(
'id' => $row['user_address_id'],
'user_id' => $row['user_address_user_id'],
'nickname' => $row['user_address_nickname'],
'address_type' => $row['user_address_type'],
'address_line_1' => $row['user_address_line_1'],
'address_line_2' => $row['user_address_line_2'],
'address_line_3' => $row['user_address_line_3'],
'city' => $row['user_address_city'],
'postcode' => $row['user_address_postcode']
);
} else {
$customers[$row['user_id']]['addresses'] = array();
}
}
return $customers;
}
trhe heavy scriptはどこですか? –
@bub MySQLクエリの読み込みに5秒かかります。 –
EXPLAINはあなたに何を言ったのですか?適切なインデックスを設定しましたか? –