Мне нужен эффективный способ нарезки результатов SQL-запроса 'JOIN' на сплошные блоки для одновременной обработки.
У меня есть две таблицы, используемые в этом запросе, которые я назову C и P.
C содержит следующие поля:
C_CID, C_f1, C_f2
P содержит следующие поля:
P_CID, P_Cat, P_Order, P_f3, P_f4
Идея состоит в том, что элементы P являются частью элементов C.
Первый запрос выглядит следующим образом:
SELECT P_CID, C_f1, C_f2, P_Cat, P_Order, P_f3, P_f4
FROM C JOIN P ON C_CID = P_CID
ORDER BY P_CID, P_Cat, P_Order
Довольно просто.
Теперь, чтобы использовать результат этого запроса, мне нужно было бы проверять строку за строкой, если я все еще использую один и тот же C_CID, так что ничего страшного, но он медленный.
Затем я предположил, что что-то вроде OFFSET и FETCH будет существовать по поведению db mgmnt GUI, который я часто использую, и вот, вот они, ожидая, что я их использую, так что все в порядке, и я пытаюсь выполнить второй запрос .
Это в основном то же самое с добавленным 'OFFSET% d ROWS FETCH NEXT% d ROWS ONLY' в конце, и я перемещаю некоторый код, чтобы привыкнуть к изменению: несколько потоков, каждый с доступом к базе данных, и чтение результата часть приходит позже, но я могу использовать данные прямо из БД, и мне нужно обновить смещение, добавив желаемое количество строк после построения запроса, которое в мьютексе я использую в своих совершенно новых потоках X.
Я выбираю около ста рядов по блокам (общий размер соединения составляет Xe ^ 6) и 8 потоков только потому, что нажимаю play и сразу же растапливаюсь из-за увеличения скорости.
А потом я проверяю результаты и о, Боже.
По сути, так как я произвольно разрезал таблицу на куски, группа элементов C с несколькими P-частями получила некоторые в конце фрагмента, а некоторые в начале следующего, aaand разбился и теперь отсутствует, и воздух начинает пахнуть моим поражением.
Я смотрю вещи и узнаю о TOP (x) WITH TIES. Что он делает, так это то, что в конце фрагмента, если последний элемент и следующий связаны столбцами в предложении ORDER BY, он добавляет его в блок (рекурсивно так).
"Выглядит хорошо", я думаю. «Теперь, как мне использовать это со смещением?»
Так что я обдумываю кое-что, осматриваю еще кое-что (31510742) и придумываю это:
WITH TEMP AS
(SELECT P_CID, P_Cat, P_Order, C_f1, C_f2, P_f3, P_f4
FROM C JOIN P ON C_CID = P_CID
ORDER BY P_CID, P_Cat, P_Order
OFFSET %d ROWS)
SELECT * FROM
(SELECT TOP %d WITH TIES *
FROM TEMP
ORDER BY P_CID)
AS TEMP2
ORDER BY P_CID, P_Cat, P_Order
(я знаю, что SELECT * FROM (SELECT) выглядит плохо, но мне нужно полное предложение ORDER BY, чтобы оно не было слишком конкретным для TOP OF TIES).
И это не работает.
Быстрое мышление, и я понимаю, что все еще обновляю смещение на статическую величину.
Теперь я должен сделать дополнительный COUNT (*) из всего этого, прежде чем выйти из мьютекса, но, эй, у меня полно потоков, работающих на полной скорости, так что это все равно победа, верно?
правый ..
Так стало так медленно.
Как оказалось, SELECT с СМЕЩЕНИЕМ ВЫБИРАЕТ все, что остается в таблице. Поэтому, хотя я никогда не вижу его, он временно загружает загрузку строк, которые я не буду использовать в этом результате запроса.
Более быстрое мышление, и у меня есть новый запрос:
WITH TEMP AS
(SELECT P_CID, P_Cat, P_Order, C_f1, C_f2, P_f3, P_f4
FROM C JOIN P ON C_CID = P_CID
ORDER BY P_CID, P_Cat, P_Order
OFFSET %d ROWS
FETCH NEXT %d + %d ROWS ONLY)
SELECT * FROM
(SELECT TOP %d WITH TIES *
FROM TEMP
ORDER BY P_CID)
AS TEMP2
ORDER BY P_CID, P_Cat, P_Order
с выборкой, которая творит чудеса.
Первый новый% d имеет то же значение, что и TOP, а второй - это максимальное количество элементов P, прикрепленных к одному и тому же элементу C (COUNTed в начале выполнения однострочным запросом) минус один. Если вы не понимаете, почему просто нарисуйте сценарий наихудшего случая на бумаге: самый мощный элемент C начинается прямо в конце фрагмента. На моих C и P это 20, и я знаю, что это никогда не будет намного больше, так что на самом деле так эффективно делать.
Теперь есть много вещей, работающих вместе, надо работать, ПРАВИЛЬНО?
И это так. Но это безобразно. И есть слишком много вещей, чтобы отслеживать. И это адаптация, когда мне нужно другое поле (* из * того, что я хочу, черт побери). И я просто ЗНАЮ, что должен быть более простой способ сделать это.
Пожалуйста, скажите мне, как.