簡體   English   中英

嵌套循環和SQL查詢; 需要速度

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM