2009-08-28 16 views
0

ねえ。私はこれらの2つのテーブルを1:nの関係で持っています。GROUP BY最適化

CREATE TABLE IF NOT EXISTS `de_locations` (
`id` int(11) NOT NULL auto_increment, 
`user_id` int(11) default NULL, 
`author_id` int(11) NOT NULL, 
`city_id` int(11) NOT NULL, 
`district_id` int(11) NOT NULL, 
`title` varchar(150) collate utf8_unicode_ci NOT NULL, 
`description` tinytext collate utf8_unicode_ci, 
`lat` double NOT NULL, 
`lng` double NOT NULL, 
`stars` double default '0', 
`comments` mediumint(9) default '0', 
`flag` tinyint(4) default '0', 
PRIMARY KEY (`id`), 
KEY `user_id` (`user_id`), 
KEY `flag` (`flag`), 
KEY `rating_district` (`district_id`,`stars`,`comments`), 
KEY `rating_city` (`city_id`,`stars`,`comments`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=15 ; 

CREATE TABLE IF NOT EXISTS `de_location2category` (
`id` int(11) NOT NULL auto_increment, 
`location_id` int(11) NOT NULL, 
`cat_id` mediumint(9) NOT NULL, 
PRIMARY KEY (`id`), 
UNIQUE KEY `rel` (`location_id`,`cat_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=14 ; 

位置は、複数のカテゴリに配置することができます。例えば

場所:「ピザハット」 カテゴリー:「イタリア料理」、「ファーストフード」

これらのカテゴリは親カテゴリ食品の子カテゴリです。

今、カテゴリの食品内のすべての場所を選択したいと思います。

私はGROUP BYが必要です。なぜなら、複数のカテゴリに関連する場所が重複していてもいいからです。しかし、このクエリは一時的なテーブルを作成し、filesortを使用します。 GROUP BYを残しても問題ありませんが、私はそれを必要としています...

別のインデックスを追加しましたか?それとも私の計画に何か悪いですか? この問題をどうやって解決しますか?どうもありがとう。

+0

「しかし、このクエリは一時テーブルを構築し、filesortレコードを使用しています。」だから何?それがリレーショナルデータベースの仕組みです。それのどこが悪いんだい?重複を取り除くことを他にどのように提案しますか? –

+0

http://dev.mysql.com/doc/refman/5.0/en/order-by-optimization.html "場合によっては、インデックスを使ってORDER BYを解決することはできませんが、インデックスを使用して行を検索します*あなたはORDER BYを異なるキーで使用します:SELECT * FROM t1 ORDER BY key1、key2; * " – Amber

+0

"何が間違っていますか?パフォーマンス。単純なSELECTでは、GROUP BYは必ずしも一時テーブルを強制しません。この場合、それを達成する方法はありませんか? また、インデックスrating_cityはGROUP BYで使用されません。 – Status4

答えて

0

なぜ使用しないのですかDISTINCT a.id?

+0

GROUP BYと同じ結果:テンポラリテーブルとファイルセット – Status4

+0

はい、それはあなたが複数のキーでソートしているためです。 DISTINCTはGROUP BYよりはるかに優れたものを実際に実現しようとしています。 – Amber

+0

問題はWHERE句のインデックス「rel」とORDER BY句の「rating_city」というインデックスを使用しているということですか? そのため、私はインデックスを変更する機会がありませんでしたか? だから私は一時的なテーブルとfilesortで生きなければなりませんか? 申し訳ありません、いくつかの言語の問題があります... – Status4

1

あなたの問題は、クエリが遅いことだと思います。テンポラリファイルとファイルポートを心配する必要はありませんが、なぜクエリが遅いのですか。 EXPLAIN {yourquery}の出力を追加して、正確に何が起きているかを確認できます。

またはあなたはまた、サブクエリを試すことができます。

SELECT a.id, a.title, a.description, a.street, a.hnr, ROUND(a.stars) as stars, a.comments, a.lat, a.lng 
FROM de_locations as a 
WHERE 
a.id IN (SELECT DISTINCT b.location_id FROM de_location2category as b WHERE b.cat_id BETWEEN 0 AND 100) 
AND a.city_id = 1000 
GROUP BY a.id 
ORDER BY a.stars DESC, a.comments DESC 
+0

ヘイジェイ、ありがとうございます。私はこれを試してみるつもりです。 – Status4