Reputation: 13541
I have a a Screening
table, which holds a number of screenings, primary key is an int.
I also have 6 other tables (LengthMeasurement
, WeightMeasurement
etc), which are linked with a foreign key constraint to the Screening
table.
In order to get the screening and all of its related information, I first used an INNER join like:
SELECT *
FROM [user].[Screening] scr
INNER JOIN [user].[LengthMeasurement] lm ON scr.Id = lm.ScreeningId
INNER JOIN [user].[WeightMeasurement] wm ON scr.Id = wm.ScreeningId
INNER JOIN [user].[Note] n ON scr.Id = n.ScreeningId
INNER JOIN [user].[IntakeRegistration] ir ON scr.Id = ir.ScreeningId
INNER JOIN [user].[RiskProfile] rfr ON scr.Id = rfr.ScreeningId
INNER JOIN [user].[OncologyTasteAnamnesis] ota ON scr.Id = ota.ScreeningId
WHERE scr.UserId = 2
However, even with a small amount of data, this already takes like 2 seconds and gets more than 30.000 rows (cartesian product).
If I do the same, but this time only with simple SELECTS, like:
SELECT * FROM [user].[Screening] scr WHERE UserId = 2
SELECT * FROM [user].[LengthMeasurement] WHERE [ScreeningId] IN
(
SELECT Id FROM [user].[Screening]
WHERE UserId = 2
)
SELECT * FROM [user].[WeightMeasurement] WHERE [ScreeningId] IN
(
SELECT Id FROM [user].[Screening]
WHERE UserId = 2
)
SELECT * FROM [user].[Note] WHERE [ScreeningId] IN
(
SELECT Id FROM [user].[Screening]
WHERE UserId = 2
)
SELECT * FROM [user].[IntakeRegistration] WHERE [ScreeningId] IN
(
SELECT Id FROM [user].[Screening]
WHERE UserId = 2
)
SELECT * FROM [user].[RiskProfile] WHERE [ScreeningId] IN
(
SELECT Id FROM [user].[Screening]
WHERE UserId = 2
)
SELECT * FROM [user].[OncologyTasteAnamnesis] WHERE [ScreeningId] IN
(
SELECT Id FROM [user].[Screening]
WHERE UserId = 2
)
Like this it's a few milliseconds, and I retrieve only the rows needed (35).
So obviously the second way is fasted, but I was wondering if this is really a good idea, of maybe there are other solutions to make this simple query fast?
Upvotes: 1
Views: 196
Reputation: 1270401
You are joining along different dimensions, which is resulting in the Cartesian product for a single user.
Clearly, the INNER JOIN
does not return a reasonable result set, because you are getting way more rows than you need.
If the separate queries meet your needs than that is definitely a feasible alternative. You cannot readily combine them into a single query using UNION ALL
, because the columns are (in all likelihood) quite different.
Otherwise, you need to decide on the result set that you actually want. Then, you can ask specifically about how to return that.
Upvotes: 2