Czy zmienić bazę danych?

0

Witam,
Na swoje potrzeby napisałem aplikację w c#, która wstawia i pobiera dane z bazy danych. Na ten moment mając 8 milionów rekordów pobranie 1600 rekordów zajmuje mi ponad minutę (zapytanie wykorzystuje EXIST i relacje z innymi tabelami). Baza danych jest uruchomiona przez Microsoft sql server a wszystko działa na VPS. Problem w tym, że ten system zarządzania bazą zabiera mi 3,5gb pamięci ram, no i działa to dość wolno. Także moje pytanie jest następujące: czy powinienem zmienić to na jakieś inne rozwiązanie? Możecie mi coś polecić?

1

Spróbować zoptymalizować bazę?
Sprawdź co jest wąskim gardłem, może brakuje jakiegoś indeksu czy coś.
1600 to bardzo mało, nawet jak masz po drodze kilka joinów.

0

Off topic - 3.5 gb RAM starcza na trzymanie w pamięci 8 mln rekordów jeśli rekordy maja po ok 400 bajtów. Ja sobie tak czasem te dane w RAM trzymam.
Działa to zarąbiście szybko nawet jak nie używam indeksów za bardzo tylko robię naiwny in memory full scan :-)

0

Wygląda to tak:

CREATE TABLE users (
    id int INT NOT NULL IDENTITY(1,1) PRIMARY KEY,,
    name VARCHAR(50),
   ....
);

CREATE TABLE restaurants(
    id int INT NOT NULL IDENTITY(1,1) PRIMARY KEY,,
    name VARCHAR(50),
    profileId int,
    toVisit int
   ....
);

CREATE TABLE occurences(
    id int INT NOT NULL IDENTITY(1,1) PRIMARY KEY,,
    userId int,
    profileId
);

A kod wyłuskujący dane:

SELECT TOP(40) profileId FROM restaurants where NOT EXISTS (SELECT profileId FROM Occurences WHERE users.Id=" + input.Id+ " and restaurants.profileId = Occurences.profileId) and toVisit>0 and profileId>0 ORDER BY case when toVisit <= 0 then 1 else 0 end, Priority DESC, ToSecond;

W skrócie:
Mam bazę z 10 000 użytkowników i 10 000 restauracji. Chciałbym za każdym razem pobrać 40 restauracji których dany użytkownik nigdy nie odwiedził, i następnie dodać te 40 jako odwiedzone przez niego.

Bez części case trwa to prawie tyle samo. Kod wykonuję dla listy z 40 elementami input.

0

Może to Ci pomoże : https://github.com/StackExchange/Dapper

1
SELECT TOP(40) r.profileId FROM restaurants r left join occurences o on (r.profileid=o.profileid and o.userid=@uid) where o.id is null and r.toVisit>0 and r.profileId>0 ORDER BY r.Priority DESC, r.ToSecond;

do parametru @uid przekaż warość input.id, dodaj też odpowiednie indeksy na tabele i powinno śmigać.
w sortowaniu case nie jest potrzebny, ponieważ i tak wskazujesz tylko te rekordy z polem tovisit większym od 0

0

To w końcu 8 mln czy 10 tys rekordów?
Ile trwa wykonanie samego zapytania SQL?

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