I’m working on a query to look for certain values in related tables. Let’s say I have a table TableA and bunch of other tables that have foreign keys linked back to TableA. I want to scan all of these related tables and check if at least 1 record with these values exist. I’m doing a query like the one below for about 7 tables (1 table can actually contain more than 1 foreign key relating it back to TableA):
SELECT
TableA.Field1,
TableA.Field2,
Table1Join.TableBPrimaryKey,
Table2Join.TableCPrimaryKey,
Table3Join.TableDPrimaryKey,
Table4Join.TableEPrimaryKey,
Table5Join.TableFPrimaryKey,
Table6Join.TableGPrimaryKey,
Table7Join.TableHPrimaryKey,
Table8Join.TableIPrimaryKey
/* As more JOINs are added below which result in more fields listed here in
the SELECT statement, the query slows down by a lot. If I simply add JOIN’s
without referencing their fields in the SELECT statement here, it runs fast
*/
FROM
TableA
/* Scan 1st related table */
INNER JOIN
(SELECT
TableAAlias.PrimaryKey,
MAX(TableB.PrimaryKey) AS TableBPrimaryKey
FROM
TableA TableAAlias
LEFT OUTER JOIN
TableB ON TableB.ForeignKey = TableAAlias.PrimaryKey
GROUP BY
TableAAlias.PrimaryKey) AS Table1Join ON Table1Join.PrimaryKey = TableA.PrimaryKey
/* Scan 2nd related table */
INNER JOIN
(SELECT
TableAAlias.PrimaryKey,
MAX(TableC.PrimaryKey) AS TableBPrimaryKey
FROM
TableA TableAAlias
LEFT OUTER JOIN
TableC ON TableC.ForeignKey = TableAAlias.PrimaryKey
GROUP BY
TableAAlias.PrimaryKey) AS Table2Join ON Table2Join.PrimaryKey = TableA.PrimaryKey
/* Scan 3rd related table */
INNER JOIN
(SELECT
TableAAlias.PrimaryKey,
MAX(TableD.PrimaryKey) AS TableDPrimaryKey
FROM
TableA TableAAlias
LEFT OUTER JOIN
TableD ON TableD.ForeignKey = TableAAlias.PrimaryKey
GROUP BY
TableAAlias.PrimaryKey) AS Table3Join ON Table3Join.PrimaryKey = TableA.PrimaryKey
/* Scan 4th related table */
INNER JOIN
(SELECT
TableAAlias.PrimaryKey,
MAX(TableE.PrimaryKey) AS TableEPrimaryKey
FROM
TableA TableAAlias
LEFT OUTER JOIN
TableE ON TableE.ForeignKey = TableAAlias.PrimaryKey
GROUP BY
TableAAlias.PrimaryKey) AS Table4Join ON Table4Join.PrimaryKey = TableA.PrimaryKey
/* Scan 5th related table */
INNER JOIN
(SELECT
TableAAlias.PrimaryKey,
MAX(TableF.PrimaryKey) AS TableFPrimaryKey
FROM
TableA TableAAlias
LEFT OUTER JOIN
TableF ON TableF.ForeignKey = TableAAlias.PrimaryKey
GROUP BY
TableAAlias.PrimaryKey) AS Table5Join ON Table5Join.PrimaryKey = TableA.PrimaryKey
/* Scan 6th related table */
INNER JOIN
(SELECT
TableAAlias.PrimaryKey,
MAX(TableG.PrimaryKey) AS TableGPrimaryKey
FROM
TableA TableAAlias
LEFT OUTER JOIN
TableG ON TableG.ForeignKey = TableAAlias.PrimaryKey
GROUP BY
TableAAlias.PrimaryKey) AS Table6Join ON Table6Join.PrimaryKey = TableA.PrimaryKey
/* Scan 7th related table */
INNER JOIN
(SELECT
TableAAlias.PrimaryKey,
MAX(TableH.PrimaryKey) AS TableHPrimaryKey
FROM
TableA TableAAlias
LEFT OUTER JOIN
TableH ON TableH.ForeignKey = TableAAlias.PrimaryKey
GROUP BY
TableAAlias.PrimaryKey) AS Table7Join ON Table7Join.PrimaryKey = TableA.PrimaryKey
/* Scan 8th related table */
INNER JOIN
(SELECT
TableAAlias.PrimaryKey,
MAX(TableI.PrimaryKey) AS TableIPrimaryKey
FROM
TableA TableAAlias
LEFT OUTER JOIN
TableI ON TableI.ForeignKey = TableAAlias.PrimaryKey
GROUP BY
TableAAlias.PrimaryKey) AS Table8Join ON Table8Join.PrimaryKey = TableA.PrimaryKey
Most of these tables contain over 100,000 records. When I don’t use fields derived from joins in the main SELECT statement, the query runs relatively fast (about 25 seconds). When I use some of the fields, it runs for about the same time but as I add more fields derived from the JOINs, the query halts to a crawl and may run for hours. There’s no rhyme or reason to this as I cannot catch what’s causing this. I can add a field and then it starts running slow, then I remove another field that was there before when it ran fast and add the one that seemingly caused the issue and it runs fast again. I can of course break this query down into 7 individual queries and create a temp-table (which I have done trying to find the cause), in which case it runs relatively fast, but I cannot use temp tables. I understand the query is probably not optimized, but I’m not a SQL guru so I’m not sure where to begin to optimize its performance.