Разбивка элементов из разных источников - PullRequest
0 голосов
/ 05 ноября 2018

Вот проблема, с которой я сталкиваюсь: мне нужно перечислить некоторые пункты. Эти предметы поступают из разных источников (скажем, таблица A, таблица B, таблица C), с разными атрибутами и характером (хотя некоторые являются общими). ​​

Как я могу объединить их в список, который разбит на страницы?

Варианты, которые я рассмотрел:

  • Сначала получите их все, затем отсортируйте и разбейте на страницы в коде. Это не работает, потому что слишком много элементов (тысяч), а производительность - беспорядок.

  • Объедините их в представлении SQL с их общими атрибутами, после выполнения запроса SQL перезагрузите только разбитые на страницы элементы, чтобы получить остальные их атрибуты. Пока это работает, но может быть трудно поддерживать, если источники меняются / увеличиваются.

Знаете ли вы другие варианты? По сути, каков наиболее используемый / рекомендуемый способ разбиения на страницы элементов из двух источников данных (либо в SQL, либо непосредственно в коде).

Спасибо.

Ответы [ 2 ]

0 голосов
/ 06 ноября 2018

Если UNION решит проблему, вот несколько советов по синтаксису и оптимизации.

Это обеспечит страницу 21 из 10 строк:

(
  ( SELECT ... LIMIT 210 )
  UNION  [ALL|DISTINCT]
  ( SELECT ... LIMIT 210 )
) ORDER BY ... LIMIT 10 OFFSET 200

Обратите внимание, что 210 = 200 + 10. Вы не можете доверять, используя OFFSET во внутреннем SELECTs.

Используйте UNION ALL для скорости, но если между SELECTs могут быть повторяющиеся строки, тогда явно скажите UNION DISTINCT.

Если вы уберете слишком много скобок, вы получите либо синтаксические ошибки, либо «неправильные» результаты.

Если вы получите подзапрос, повторите ORDER BY, но не LIMIT:

SELECT ...
    FROM (
           ( SELECT ... LIMIT 210 )
           UNION  [ALL|DISTINCT]
           ( SELECT ... LIMIT 210 )
           ORDER BY ... LIMIT 10 OFFSET 200
         ) AS u
    JOIN something_else  ON ...
    ORDER BY ...

Одна из причин, которая может включать JOIN, связана с производительностью - подзапрос u свел результирующий набор до 10 строк, поэтому JOIN будет иметь только 10 вещей для поиска. Помещение JOIN внутри приведет к большому количеству соединений, а затем сократится до 10.

0 голосов
/ 05 ноября 2018

Мне действительно пришлось совсем недавно отвечать на похожую ситуацию, в частности сообщая о двух больших таблицах и разбивая их на страницы. Я пришел к ответу, используя следующие подзапросы:

SELECT
    t1.id as 't1_id',
    t1.name as 't1_name',
    t1.attribute as 't1_attribute',
    t2.id as 't2_id',
    t2.name as 't2_name',
    t2.attribute as 't2_attribute',
    l.attribute as 'l_attribute'
FROM (
    SELECT
        id, name, attribute
    FROM
        table1
    /* You can perform joins in here if you want, just make sure you're using your aliases right */
    /* You can also put where statements here */
    ORDER BY
        name DESC, id ASC
    LIMIT 0,50
    ) as t1
INNER JOIN (
    SELECT
        id,
        name,
        attribute
    FROM
        table2
    ORDER BY
        attribute ASC
    LIMIT 250,50
    ) as t2
    ON  t2.id IS NOT NULL
LEFT JOIN
    linkingTable as l
    ON  l.t1Id = t1.id
    AND l.t2Id = t2.id
/* Do your wheres and stuff here */
/* You shouldn't need to do any additional ordering or limiting */
...