Widok zmaterializowany a LEFT JOIN

0

Mam taki widok:

CREATE VIEW vProductHeaders
WITH SCHEMABINDING
AS  
    SELECT p.[Id], p.[Name], p.[Price], p.[Discount], p.[CategoryId], COUNT_BIG(r.[ProductId]) as [RateCount], SUM(r.[Stars]) as [RateSum]
    FROM dbo.[Products] p
    LEFT JOIN dbo.[Rates] r
    ON p.[Id] = r.[ProductId]
    GROUP BY p.[Id], p.[Name], p.[Price], p.[Discount], p.[CategoryId];
GO

W trakcie próby utworzenia indeksu leci błąd, że się nie da, bo left join. Używam tego widoku do wyszukiwania produktów. Jeśli produkt nie ma żadnej oceny, to nie pojawi się na liście w przypadku inner joina, czyli przy tworzeniu produktu muszę mu nadać jakąś początkową ocenę, co jest trochę słabe. Jest jakieś walkaround tego?

0

W sumie na stacku znalazłem coś podobnego wcześniej. Wydaje mi się to brzydkie, ale rozumiem, że innego rozwiązania nie ma. W innych bazach też tak jest? W Postgresie by ten left join zadziałał?

0

Nie wiem czy by zadziałał, pytanie czy faktycznie masz problem, że chcesz ten widok materializować?

0

No w sumie nie muszę, bawię się tylko w side-projekcie. @neves siedzi chyba w Postgresie. Zadziałałby tam left join?

4

Zadziała, tyle że w postgresie zmaterializowane widoki same się nie odświeżają .... :|

0

O, a jakbyś postąpił w przypadku SQL Servera?

2

Jak patrzę na listę ograniczeń (praktycznie wszystko jest zabronione), to nie widzę innego sposobu niż w stylu który już został przytoczony.

Po zastanowieniu się, to w ogóle bym raczej zrezygnował ze zrobienia indeksu na całym joinie.
Spróbowałbym zrobić jeden indeks na widoku:
r.[ProductId], COUNT_BIG(r.[ProductId]) as [RateCount], SUM(r.[Stars])
w tabeli Products mamy zapewne indeks po Id, i przy lekkiej modyfikacji oryginalnego zapytania tak by korzystało z nowo utworzonego widoku, query planer sql servera powinien użyć operatora merge join, i powinno to pięknie śmigać bez materializacji całego zapytania.

2

LEFT JOIN w widokach w PostgreSQL można spokojnie wykorzystywać.
A jeśli jest MATERIALIZED, to można na tych dwóch tabelach trigger after statement zrobić odświeżający....

2

Hmm, z tego co rozumiem, to lista produktów jest raczej stała (wolno zmienna), a to co się zmienia to rates (dużo szybciej niż lista produktów). Próbowałeś coś takiego jak niżej?

  1. materialized view na samych rates
  2. poindeksować taki mview po productId
  3. Zrobić zwykły widok między produktami i zmaterializowanym widokiem po productId, który zawiera tego left outer joina
  4. odpytywać zwykły widok

edycja:
Doczytałem i @neves zaproponował już takie podejśćie ;-)

1 użytkowników online, w tym zalogowanych: 0, gości: 1