[英]Nested loops and SQL queries; need for speed
我在解決迭代SQL查詢問題時遇到了麻煩( 我需要解決 ),而我正在嘗試找到一種替代方法。
( 另外,不幸的是,AJAX並不真正適合 )
鑒於我有以下位置數據表:
Country
country_id
name
State
state_id
country_id
name
City
city_id
state_id
name
現在,我正在嘗試提取所有數據,但是實際上它非常小( 147個城市,分布在64個州之間,分布在2個國家之間 ),但是由於我不斷地循環遍歷,它會永遠占用時間:
// this is pseudo-code, but it gets the point across
$countries = getCountries();
foreach($countries as &$country){
$country['states'] = $states = getStates($country['country_id']);
foreach($states as &$state){
$state['cities'] = getCities($state['state_id']);
}
}
我采用這種方式的原因是,我的最終結果集需要采用以下形式:
$countries = array(
array(
'name' => 'country_name',
'id' => 'country_id',
'states' => array(
array(
'name' => 'state_name',
'id' => 'state_id',
'cities' => array(
array(
'name' => 'city_name',
'id' => 'city_id',
),
// ... more cities
),
),
// ... more states
),
),
// ... more countries
);
我似乎無法繞過更快的方法。 查詢分層數據有哪些選擇?
修訂:
$sql = "SELECT
`dbc_country`.`name` as `country_name`,
`dbc_state`.`name` as `state_name`,
`city_id`,
`dbc_city`.`name` as `city_name`,
`latitude`,
`longitude`
FROM
`dbc_city`
INNER JOIN
`dbc_state` ON `dbc_city`.`state_id` = `dbc_state`.`state_id`
INNER JOIN
`dbc_country` ON `dbc_state`.`country_id` = `dbc_country`.`country_id`";
$locations = array();
foreach($datasource->fetchSet($sql) as $row){
$locations[$row['country_name']][$row['state_name']][] = array(
$row['city_id'],
$row['city_name'],
$row['latitude'],
$row['longitude'],
);
}
( 我還刪除了國家/地區的id
值,因為它們無用地占用了空間 )
在SQL中進行聯接會更快
然后遍歷單個(較大)結果集。
我要么使用一個查詢:
SELECT co.name AS CountryName
, st.name AS StateName
, ci.name AS CityName
FROM Country AS co
LEFT JOIN State AS st
ON st.country_id = co.country_id
LEFT JOIN City AS ci
ON ci.state_id = st.state_id
ORDER BY CountryName
, StateName
, CityName
或三個(如果您有很多記錄,並且擔心從MySQL到應用程序代碼的連接會發送數十萬次"United States of America"
):
--- **GetCountries**
SELECT co.country_id
, co.name AS CountryName
FROM Country AS co
ORDER BY CountryName
--- **GetStates**
SELECT co.country_id
, st.state_id
, st.name AS StateName
FROM Country AS co
JOIN State AS st
ON st.country_id = co.country_id
ORDER BY CountryName
, StateName
--- **GetCities**
SELECT co.country_id
, st.state_id
, ci.city_id
, ci.name AS CityName
FROM Country AS co
JOIN State AS st
ON st.country_id = co.country_id
JOIN City AS ci
ON ci.state_id = st.state_id
ORDER BY CountryName
, StateName
, CityName
數據庫設計的通用方法強調盡可能多地工作,並且查詢盡可能少。 它看起來不錯。 但是引用該線程標題“查詢效率”,該方法不適用於MySQL。 僅供參考,MySQL旨在非常有效地處理連接和斷開連接,並非常快速地響應小型和簡單查詢,因此,只要您立即釋放排序查詢中的內存,我認為還可以。 此外,如果您的記錄不斷增長(例如增加到100000條記錄),那么您可能會三思而后行地使用JOIN語句。
如果您的數據看起來像這樣呢?
Table: country
iso_country_code country_name
--
CA Canada
US United States of America
Table: state
iso_country_code state_abbr state_name
--
US NE Nebraska
CA NB New Brunswick
Table: city
iso_country_code state_abbr city_name
--
US NE Lincoln
US NE Arapahoe
CA NB Dalhousie
CA NB Miramichi
您可以使用代碼和縮寫詞代替全名嗎?
即使不能,也可以通過單個SELECT語句獲得所有必要的行,然后遍歷行以填充數組。 (您也可以使用ID號來執行此操作,但是使用ID號始終必須進行聯接。使用代碼和縮寫,通常僅使用代碼或縮寫就能滿足用戶的需求。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.