Как найти все строки подключенной базы данных с помощью CTE - PullRequest
0 голосов
/ 04 апреля 2019

У меня есть сложный набор строк базы данных, которые связаны через таблицу ассоциации в родительских / дочерних отношениях для системы управления запасами.Родитель состоит из дочерних элементов, а дочерние элементы также могут быть созданы из дочерних элементов и т. Д.Кроме того, дети могут иметь более одного родителя (например, винт используется многими элементами и является дочерним для всех этих элементов).

Я создал запрос с использованием CTE, который найдет всех родителейначального узла, а затем проведите назад, чтобы найти всех детей под родителями.Однако это не позволяет получить все потенциальные связанные узлы с исходным элементом.Это связано с тем, что каждый потенциальный цикл подключенных узлов может добавлять какого-либо родителя или дочернего элемента, который еще не был обнаружен, когда вы отклоняетесь от начальной точки.Я попытался добавить больше блоков CTE, которые берут предыдущие результаты и соединяются снова, но после нескольких итераций это становится очень медленным.С моими данными о клиенте первые несколько циклов бывают быстрыми, но раунд 4 занимает 24 секунды, а раунд 5 - 12 минут.

Вот мой пример запроса, который я тестировал с глубиной 5 CTE.

;WITH cte 
  AS (SELECT a.itemid 
        FROM item a 
       WHERE a.itemid = 1732 
       UNION ALL 
      SELECT a.itemid 
        FROM item a 
        JOIN assemblylineitem b 
          ON a.itemid = b.itemid 
        JOIN cte c 
          ON b.componentitemid = c.itemid), 
cte2 
  AS (SELECT a.itemid
        FROM item a 
       WHERE a.itemid IN (SELECT itemid FROM cte) 
       UNION ALL 
      SELECT a.itemid 
        FROM item a 
        JOIN assemblylineitem b 
          ON a.itemid = b.componentitemid 
        JOIN cte c 
          ON b.itemid = c.itemid),
cte3 
  AS (SELECT a.itemid 
        FROM item a 
       WHERE a.itemid in (SELECT itemid FROM cte2)
       UNION ALL 
      SELECT a.itemid 
        FROM item a 
        JOIN assemblylineitem b 
          ON a.itemid = b.itemid 
        JOIN cte2 c 
          ON b.componentitemid = c.itemid), 
cte4 
  AS (SELECT a.itemid
        FROM item a 
       WHERE a.itemid IN (SELECT itemid FROM cte3) 
       UNION ALL 
      SELECT a.itemid 
        FROM item a 
        JOIN assemblylineitem b 
          ON a.itemid = b.componentitemid 
        JOIN cte3 c 
          ON b.itemid = c.itemid),
cte5
  AS (SELECT a.itemid 
        FROM item a 
       WHERE a.itemid in (SELECT itemid FROM cte4)
       UNION ALL 
      SELECT a.itemid 
        FROM item a 
        JOIN assemblylineitem b 
          ON a.itemid = b.itemid 
        JOIN cte4 c 
          ON b.componentitemid = c.itemid)

SELECT distinct(itemid)
FROM   cte5
order by itemid

Есть ли способ структурировать запрос, который соединит все потенциальные подключенные узлы с начальной точкой и будет эффективен?

...