0

反復的な 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た。無駄にスペースを占めていたからです)

4

4 に答える 4

4

SQLで結合を行う方がはるかに高速です

次に、単一の (より大きな) 結果セットを反復処理します。

于 2011-07-26T01:18:10.420 に答える
1

1 つのクエリを使用します。

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

"United States of America"または 3 つ (多数のレコードがあり、MySQL からアプリケーション コードへの接続を介して何十万回も送信することを心配している場合):

--- **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
于 2011-07-26T01:46:16.840 に答える
0

代わりに、データが次のようになったらどうしますか?

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

フルネームの代わりにコードと略語を使用できますか?

できなくても、1 つの SELECT ステートメントで必要なすべての行を取得し、行をたどって配列にデータを入力することができます。(ID 番号でも同じことができますが、ID 番号では常に結合を行う必要があります。コードと略語を使用すると、多くの場合、コードまたは略語だけでユーザーを満足させることができます。)

于 2011-07-26T01:56:23.607 に答える
0

データベース設計の一般的なアプローチでは、できるだけ少ないクエリで、できるだけ多くの作業を行うことが強調されています。その見た目は正しい。しかし、このスレッドのタイトル「Query Efficiency」を引用すると、そのアプローチは MySQL にはあまり当てはまりません。参考までに、MySQL は、接続と切断を非常に効率的に処理し、小さくて単純なクエリに非常に迅速に応答するように設計されているため、シーケンス クエリのメモリをすぐに解放する限り、問題ないと思います。さらに、レコードが (たとえば 100000 レコードに) 増加する場合は、JOIN ステートメントの使用についてよく考える必要があります。

于 2011-07-26T01:22:21.447 に答える