Sql отбор улучшений через присоединения? - PullRequest
2 голосов
/ 09 марта 2011

Как я могу улучшить следующий запрос, так как мне кажется, что я что-то упустил, и это можно сделать лучше :( У меня есть таблица A и один-ко-многим от A до BI, мне нужна информация от A и строка от Bэто связано с А. с наивысшим порядковым номером. Я придумал это:

SELECT A.*, 
 (
  SELECT B.value
  FROM   B 
  WHERE A.idB = B.id
  ORDER BY B.seqNr DESC LIMIT 1
 )
FROM A

Для меня важна производительность, так что это моя лучшая ставка?

Ответы [ 2 ]

1 голос
/ 09 марта 2011

Это, вероятно, ваш лучший выбор, особенно если вы будете посещать только небольшое количество строк из A и B.

Если вы все равно собираетесь покрывать все строки, вы можете попытаться обратитьсяпроблема с агрегацией окон, присваивающей номера строк строкам из B:

SELECT * FROM (
  SELECT A.*, B.*, ROW_NUMBER() OVER(PARTITION BY B.id ORDER BY B.seqNr DESC) AS seqidx
  FROM A JOIN B ON A.idB = B.id
) WHERE seqidx = 1

Это будет использовать много временного пространства, хотя ... рассмотрите возможность извлечения первичных ключей A и B из агрегата и соединения обратнона них позже (из вашего запроса не ясно, каковы ваши столбцы pkey, поскольку B.id, по-видимому, нет)

0 голосов
/ 09 марта 2011

Хотя больше, возможно, это будет работать лучше.

SELECT
    A.*,
    B3.value
FROM
    (
        SELECT  B.id, MAX(B.seqNr) MaxSeqNr
        FROM    B
        GROUP BY    B.id
    ) B2
            INNER JOIN
    B B3
            ON
        B2.id = B3.id AND B2.MaxSeqNr = B3.seqNr
            INNER JOIN
    A
            ON
        A.id = B3.id

Также возможно, что он будет работать хуже. Нужны реальные данные, чтобы проверить и увидеть. : -)

Кроме того, создание составного индекса на B.id, B.seqNr DESC может повысить производительность как исходного, так и этого альтернативного запроса.

Если вы можете задержать теоретических пуристов в своей организации, вы можете значительно повысить производительность, добавив поле LatestPaymentForA и используя триггер для синхронизации этого поля. Всякий раз, когда новая запись вставляется в B, обновите существующую запись B, где LastPaymentFromA имеет значение true и имеет тот же id, затем вставьте новую запись с LastPaymentFromA в значение true.

Тогда вы можете сделать что-то действительно быстрое, как это:

SELECT
    A.*,
    B.value
FROM
    A
            INNER JOIN
    B
            On
        A.id = B.id
WHERE
    B.LastPaymentFromA = 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...