0

こんにちは、ここに次の 3 つのテーブルがあります。

COUNTRIES
ID | Name | Details

Airports
ID | NAME | CountryID

Trips
ID | AirportID | Date

以下を示すリストを取得する必要があります。

AirportID | AIrport Name | Country Name | Number of Trips Made Between Date1 and Date2

これを本当に効率的にする必要があります。どのような種類のインデックスを設定する必要があり、ここで SQL クエリをどのように作成すればよいでしょうか? これを Php を使用して表示します。行った旅行の数に基づいて並べ替えることができる必要があることに注意してください。

編集==

おっと、私のSQLに言及するのを忘れていました:

私は次のことを試しました:

SELECT `c`.*, `t`.`country` AS `country_name`, COUNT(f.`id`) AS `num_trips` FROM `airports` AS `c`
 LEFT JOIN `countries` AS `t` ON  t.`id` = c.`country_id` 
 LEFT JOIN `trips` AS `f` ON f.`airportid` = c.`id` GROUP BY `c`.`id` ORDER BY `num_flights` ASC LIMIT 10

それは機能しますが、実行には非常に長い時間がかかります-さらに、私の空港テーブルには30,000を超えるエントリがあり、旅行テーブルは可変であることを考慮してください。

国テーブルから国の名前を取得しているだけです-代わりにSQLで国テーブルへの参加を除外し、代わりにインデックスがIDで値が配列から国名を取得する方が良いでしょうか国の名前?

4

2 に答える 2

2

なぜ左結合を使用しているのかわかりません。すべての旅行に空港があり、すべての空港に国がある場合、内部結合を使用すると正確な結果が得られます。

私はこれを行います:

select a.ID as AirportID, a.Name as AirportName, c.Name as CountryName, count(t.id) as NumTrips from Trips t inner join Airports a on t.AirportID = a.ID inner join Countries c on a.CountryID = c.ID where t.Date >= @StartDate and t.Date <= @EndDate group by AirportID, AirportName, CountryName order by NumTrips limit 10

@StartDateと@EndDateを適切な値に置き換えます。

結果で何を探しているのかわかりませんが、最も多くの旅行が必要だと思います。その場合は、「NumTripsdescによる注文」を実行する必要があります。これは、特に10に制限しているため、最初に最も高い値を表示します。

また、「日付」列の名前を、予約済みのSQLワードと衝突しない名前に変更することをお勧めします。私は通常、「DateCreated」や「DateOfTravel」などを使用します。

私が悪い仮定をした場合は私に知らせてください、そして私はこれを書き直すことができます。

編集:

インデックスの場合は、検索するフィールドに作成します。言い換えると、主キー(常にインデックスが付けられる必要があります)、外部キー、そしてこの場合、日付列が他の重要なインデックスになるように見えます。ただし、「空港名」で検索する場合は、そこにインデックスを追加してください。これがどこに向かっているのか、などがわかると思います。

于 2011-04-13T07:06:46.660 に答える
1

インデックスを作成し、最も重要と思わairpoirt(countryid, id)れます。trips(airportid)

count(f.id)tryの代わりに、MySQLは列count(f.airportid)をチェックする必要がありません。trips.id

于 2011-04-13T06:41:47.407 に答える