次のスキーマを持つテーブルがあります。
デバイス
- デバイスID
- 名前
サービス
- サービス ID
- 名前
ソフトウェア
- ソフトウェア ID
- 名前
デバイス_ソフトウェア
- デバイスID
- ソフトウェア ID
- 発見日
デバイス_サービス
- デバイスID
- サービス ID
- 発見日
ここで、デバイスと、そのデバイスが持つ個別のソフトウェアとサービスの数を与えるクエリを作成しようとしています。
次のクエリを実行すると、5 秒以内に結果が返されます (デバイスには 50,000 行、ソフトウェアとサービスには両方とも 200 行があり、リンク テーブルにはすべてのデバイスからすべてのソフトウェアとサービスへのリンクが含まれています。テスト目的のためだけです)。
SELECT
device.name
,COUNT(DISTINCT(device_software.softwareId))
FROM
device
LEFT OUTER JOIN
device_software ON device.deviceId = device_software.deviceId
GROUP BY device.name
ただし、両方のカウントを含めるようにクエリを拡張しようとすると、はるかに時間がかかります (〜 30 分、まだ続きます)。
SELECT
device.name
,COUNT(DISTINCT(device_software.softwareId))
,COUNT(DISTINCT(device_service.serviceId))
FROM
device
LEFT OUTER JOIN
device_service ON device.deviceId = device_service.deviceId
LEFT OUTER JOIN
device_software ON device.dDeviceId = device_software.deviceId
GROUP BY device.name
これはストアド プロシージャにあるため、2 つのカウントを個別に取得して結合することもできますが、これはハックのように思えます。パフォーマンスに大きな影響を与えることなく、単一のクエリでこれを行うためのより良い方法を誰かが知っているかどうか疑問に思っていましたか?