Navicatブログ

Cサブクエリと結合の選択 2022年11月11日 Robert Gravelle

ブログ記事 Joins versus Subqueries: Which Is Faster?では、結合はサブクエリよりも高速に実行される傾向があることを学びました。そうは言っても、これは普遍的なルールではないため、結合が望ましいと自動的に想定したくない場合があります。その記事で述べたように、クエリに多くの結合を追加する必要がある場合、データベースサーバーはより多くの作業を行う必要があり、データの取得時間が遅くなる可能性があります。この記事では、結合を使用するクエリとサブクエリを含むクエリを比較するために実行できるいくつかの簡単なテストを紹介し、どちらが最適かを選択できるようにします。

2つのクエリ、同じ結果

ほとんどの場合、クエリは結合またはサブクエリを使用して記述できます。説明のために、MySQL Sakila Sample Databaseから国とそれに関連付けられた都市と住所を共に選択するクエリを示します。最初のSELECTステートメントは結合を使用し、2番目のステートメントはサブクエリを使用してまったく同じデータをフェッチします:

SELECT
    co.Country,
    COUNT(DISTINCT ci.city_id) AS city_cnt,
    COUNT(a.city_id)           AS address_cnt
FROM country co
INNER JOIN city ci
    ON co.country_id = ci.country_id
INNER JOIN address a
    ON ci.city_id = a.city_id
GROUP BY
    co.country_id;
		
		
SELECT 
    Co.Country,
    (Select COUNT(1) 
		 FROM City Ci 
		 WHERE Ci.country_id=co.country_id) AS city_cnt,
    (Select COUNT(1) 
		 FROM Address A 
		   INNER JOIN city c on a.city_id=c.city_id 
		 WHERE C.country_id=co.country_id) AS address_cnt
From Country Co;

クエリを同時に実行できるため、結果を簡単に比較できます。それぞれの結果セットは、SQLエディタの下のそれぞれのタブに表示されます。以下の画像では、結果2タブの内容が結果1横に表示されており、簡単に比較できます:

country, cities, and addresses (142K)

クエリ実行時間

両方のステートメントが同等であることを確認したので、実行時間を比較しましょう。

これを行うためには、個々のステートメントを選択して、実行ボタンをクリックします。そのラベルは、エディタでテキストが選択される度に、選択部分を実行に変わります。画面の下部に0.020s経過時間が表示されます。

join query elapsed time (138K)

2番目のステートメントで同じことを行うと、経過時間0.021sになります。わずかな違いですが、データの量が増えると大きくなります:

subquery elapsed time (123K)

実行計画の比較

クエリの実行計画は、実行速度に関する多くの情報を明らかにすることができます。Navicatでは、説明ボタンをクリックして実行計画を表示できます。説明の結果を解釈できるようになるためにはある程度の練習が必要ですが、そうすることでクエリの効率を確認しようとする際に利益を得ることができます。

説明1タブには、最初の(結合)クエリの実行計画が表示されます。3つのSIMPLE選択が含まれていることが一目でわかります。

explain1 (99K)

一方、説明2タブには、1つのPRIMARY選択がリストされ、その後に3つのDEPENDENT SUBQUERYが続きます。深く掘り下げなくても、2番目の(サブクエリ)ステートメントを実行するために必要な追加の手順があることが既にわかります。

explain2 (42K)

結論

このブログは、Joins versus Subqueries: Which Is Faster?の記事で到達した結論を確認しているように見えますが、結合とサブクエリの両方のアプローチを比較することは価値のある演習になる可能性があります。いずれにせよ、その場で集計値を計算し、それを外部クエリで比較のために使用する必要がある場合など、サブクエリが結合よりも有利な時が今でもあります。

ブログのアーカイブ
シェア