2017-11-24 16 views
0

私はそれほどデータベースに入らず、MySql DBでランニングしているクエリに関連する疑問があります。SQL:GROUP BY vs. DISTINCT。この状況で一番良いのは何ですか?

私はこのクエリを持っている:

次のようなもの(いくつかの市場での商品のリストを表す)を返し
SELECT 
    CD.id    AS id, 
    CD.commodity_name_en AS commodity_name_en 

FROM MarketDetails AS MD 
INNER JOIN MarketDetails_CommodityDetails AS MD_CD 
     ON MD.id = MD_CD.market_details_id 
INNER JOIN CommodityDetails AS CD 
     on MD_CD.commodity_details_id = CD.id 
WHERE MD.localization_id = 1 

id     commodity_name_en                                                            
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 
1     Rice-Asia                                                              
2     Apple banana                                                             
3     Avocado                                                               
4     Red onion                                                              
5     White onion                                                              
6     Green Beans                                                              
7     Bell pepper                                                              
8     Carrot                                                               
9     Tomatoes                                                      
10     Irish potatoes                                                             
11     Maize                                                               
1     Rice-Asia                                                              
3     Avocado                                                               
5     White onion                                                              
8     Carrot                                                               
11     Maize                                                               
2     Apple banana                                                             
7     Bell pepper                                                              
9     Tomatoes                                                      
10     Irish potatoes                                                             
1     Rice-Asia 

を、あなたは(これらの商品が複数回表示されることが見ることができるように特定の商品を複数の市場で販売することができるため)。

私はすべての商品が一度しか表示されないように質問を変更したいと思います(最終的には重複のないすべての商品のリストが必要です)。

だから、私はこの方法で行うことができることを知っている:

SELECT 
    CD.id    AS id, 
    CD.commodity_name_en AS commodity_name_en 

FROM MarketDetails AS MD 
INNER JOIN MarketDetails_CommodityDetails AS MD_CD 
     ON MD.id = MD_CD.market_details_id 
INNER JOIN CommodityDetails AS CD 
     on MD_CD.commodity_details_id = CD.id 
WHERE MD.localization_id = 1 
GROUP BY id 

私はIDによってグループ化していますが、私は名前によってもグループ(それは同じである)ことができます。

私の疑問は:別名の文章を使って同じ動作を得ることができますか?

ここ読んで、解決策になることができると思わ:https://www.tutorialspoint.com/sql/sql-distinct-keyword.htm

だから私はまた、このソリューション試してみて、とてもDISTINCT 間の正確な違いは何ですか

SELECT DISTINCT 
    CD.id    AS id, 
    CD.commodity_name_en AS commodity_name_en 

FROM MarketDetails AS MD 
INNER JOIN MarketDetails_CommodityDetails AS MD_CD 
     ON MD.id = MD_CD.market_details_id 
INNER JOIN CommodityDetails AS CD 
     on MD_CD.commodity_details_id = CD.id 
WHERE MD.localization_id = 1 

同じ結果を返すようですおよびGROUP BYのソリューションですか?そして、私のようなケースで一番賢いのは何ですか?

ありがとうございました

+3

私は、次の各アプローチ –

+0

の効率をハイライト表示されますされ、各クエリにEXPLAINし、結果を掲示実行することをお勧め@ PaulDixonのコメントでは、それぞれのタイミングをベンチマークします。 – kchason

+1

'DISTINCT'クエリは、MySQLのフードの下で' GROUP BY 'によって実装されることがよくあります。私はどちらのクエリもあまりにも異なることを期待していません。 –

答えて

5

どちらのバージョンでも忘れてしまいます。あなたは一つだけのテーブルから列をしたい場合は、代わりにexistsを使用します。

SELECT CD.id, CD.commodity_name_en 
FROM CommodityDetails CD 
WHERE EXISTS (SELECT 1 
       FROM MarketDetails MD INNER JOIN 
        MarketDetails_CommodityDetails MD_CD 
        ON MD.id = MD_CD.market_details_id 
       WHERE MD_CD.commodity_details_id = CD.id AND 
        MD.localization_id = 1 
      ); 

このバージョンでは、MySQLは結果セット全体で集約を行う必要はありません - それは、大きなコスト削減することができます。これにより、元のクエリで使用されたインデックスを利用できるはずです。

注:列の別名としてasを削除しました。 CD.idのデフォルトの別名はidです。これを明示的に指定する理由はありません(入力と冗長クエリが本当に好きでない限り)。

あなたの特定の質問に関しては、それはコメントで答えられました - DISTINCTGROUP BYは非常に似た性能を持つべきです。

0

後でその結果セットから削除する必要があるだけですべてを結合しないでください。

特定の市場に存在する商品を選択したいとします。したがって、WHERE句(EXISTSまたはIN句)で商品テーブルから選択して市場を検索します。

select id, commodity_name_en 
from commoditydetails 
where id in 
(
    select md_cd.commodity_details_id 
    from marketdetails_commoditydetails md_cd 
    join marketdetails md on md.id = md_cd.market_details_id 
    where md.localization_id = 1 
); 

それとも、あなたも、どのなし、より良いが参加することを好む場合:

select id, commodity_name_en 
from commoditydetails 
where id in 
(
    select commodity_details_id 
    from marketdetails_commoditydetails 
    where market_details_id in (select id from marketdetails where md.localization_id = 1) 
); 
+0

なぜこの時間を節約できますか? – AndreaNobili

+0

まず、SQLを書くときは、クエリを読みやすく保守したいと思っています。これが私たちの最初の配慮です。商品を選択したい場合は、商品を選択します。商品は市場と結合しません。スピードについて:重複を集約して削除することは、むしろ遅いプロセスです。これを行うには、まずすべてのデータを注文する必要があります。これは、大きなテーブルではかなりの作業になります。 (小さなテーブルでは、これで大きな違いはありません) –

+1

とにかく、パフォーマンスの問題が発生した場合にのみ、クエリのスピードアップについて考えてみましょう。クエリを難読化しないでください。おそらくこれがDBMSを騙してより良い実行計画を生成する可能性があるからです。 –

関連する問題