2009-05-19 6 views
13

używam zarówno Firebird Embedded i serwer Firebird, i od czasu do czasu muszę reindex tabele stosując procedurę jak następuje:Czy Firebird wymaga ręcznego ponownego indeksowania?

CREATE PROCEDURE MAINTENANCE_SELECTIVITY 
ASDECLARE VARIABLE S VARCHAR(200); 
BEGIN 
FOR select RDB$INDEX_NAME FROM RDB$INDICES INTO :S DO 
BEGIN 
S = 'SET statistics INDEX ' || s || ';'; 
EXECUTE STATEMENT :s; 
END 
SUSPEND; 
END 

myślę, że to jest normalne przy użyciu wbudowanego, ale jest to naprawdę potrzebne przy użyciu serwer? Czy istnieje sposób na skonfigurowanie serwera, aby robił to automatycznie, gdy jest to wymagane lub okresowo?

+2

Tylko notatkę. SUSPEND jest zbędny w tej procedurze. –

+0

Dzięki! Chyba skopałem to skądś. – pablo

+2

W rzeczywistości nie następuje ponowne indeksowanie, a jedynie ponowne obliczanie statystyk indeksu. Ponowne indeksowanie może być bardzo powolne na dużych tabelach. Obliczanie statystyk jest zawsze szybkie. –

Odpowiedz

20

Po pierwsze, chciałbym zaznaczyć, że nie jestem ekspertem od Firebird, więc odpowiadam na podstawie tego, jak działa SQL Server.

W takim przypadku odpowiedź brzmi "tak" i "nie".

Indeksy są oczywiście aktualizowane na serwerze SQL, w tym sensie, że jeśli wstawisz nowy wiersz, wszystkie indeksy dla tej tabeli będą zawierały ten wiersz, więc zostanie znaleziony. Zasadniczo nie ma potrzeby ponownego indeksowania tabel, aby ta część działała. To jest część "nie".

Problem jednak nie dotyczy indeksu, ale statystyki. Mówisz, że musisz ponownie zindeksować tabele, ale potem pokazujesz kod, który manipuluje statystykami, i dlatego odpowiadam.

Krótka odpowiedź brzmi, że statystyki powoli znikają z upływem czasu. Mogą nie ulec pogorszeniu do punktu, w którym nie nadają się do użytku, ale ulegną pogorszeniu z poziomu, na którym się znajdują, kiedy je odtwarzasz/ponownie obliczasz. To jest "tak".

Głównym problemem z nieaktualnymi statystykami jest to, że jeśli rozkład kluczy w indeksach zmienia się drastycznie, statystyki mogą tego nie wykryć od razu, a zatem optymalizator zapytań wybierze niewłaściwe indeksy w oparciu o stare, stare, dane statystyczne, które ma pod ręką.

Na przykład, powiedzmy, że jeden z twoich indeksów ma statystyki, które mówią, że klucze są zbite razem na jednym końcu przestrzeni wartości (na przykład, kolumna z dużą liczbą zer i jedynek). Następnie wstawiasz wiele wierszy z wartościami, które sprawiają, że indeks zawiera wartości rozłożone na całe spektrum.

Jeśli teraz wykonasz zapytanie, które używa sprzężenia z innej tabeli, w kolumnie o niskiej selektywności (również dużej liczbie zer i jedynek) w porównaniu do tabeli z tym indeksem, optymalizator zapytań może wydedukować, że ten indeks jest dobrze, ponieważ pobierze wiele wierszy, które będą używane w tym samym czasie (są na tej samej stronie danych).

Jednakże, ponieważ dane uległy zmianie, przeskoczą cały indeks, aby znaleźć odpowiednie elementy, a zatem nie będą tak dobre.

Po ponownym obliczeniu statystyk optymalizator zapytań może zobaczyć, że ten indeks jest nieoptymalny dla tego zapytania, a następnie wybrać inny indeks, który jest bardziej odpowiedni.

Zasadniczo należy okresowo przeliczać statystyki, jeśli dane się zmieniają. Jeśli twoje dane rzadko się zmieniają, prawdopodobnie nie musisz robić tego zbyt często, ale nadal dodawałbym pracę konserwacyjną z pewną regularnością, która to robi.

Co do tego, czy można poprosić Firebirda o zrobienie tego samodzielnie, to znowu jestem na cienkim lodzie, ale podejrzewam, że istnieje. W SQL Server można ustawić zadania konserwacji, które wykonują to zgodnie z harmonogramem, a przynajmniej powinieneś być w stanie uruchomić plik wsadowy z harmonogramu systemu Windows, aby zrobić coś podobnego.

+3

+1 doskonałe wyjaśnienie – idursun

+0

Dokładnie, chciałem powiedzieć, że w rzeczywistości przeliczanie statystyk może być kluczowe, gdy wprowadzana jest duża liczba danych, i martwię się, że Firebird nie przeliczy ich automatycznie i nie ma (oczywiste) sposób zrobić to z zadaniem, jak w SQL Server. – pablo

+1

Wtedy domyślam się, że plik wsadowy, który wywołuje właściwe narzędzia wiersza poleceń i wykonuje instrukcje SQL lub sprocs, których potrzebujesz, jest jedynym wyborem, jaki masz, chyba że czujesz się żądny przygód i możesz zrobić narzędzie samemu :) –

7

To nie powoduje ponownego indeksowania, przelicza wagi dla indeksów, które są używane przez optymalizator do wyboru najbardziej optymalnego indeksu. Nie musisz tego robić, dopóki rozmiar indeksu nie zmieni się bardzo. Jeśli utworzysz indeks przed dodaniem danych, musisz wykonać ponowne obliczenie.

Wbudowany i serwer powinien mieć dokładnie tę samą funkcjonalność oprócz modelu procesu.

+0

Masz rację. W każdym razie ma to ogromny wpływ na wydajność. Chodzi ci o to, że żaden z nich nie zrobi tego automatycznie? – pablo

+0

Indeks jest aktualizowany, gdy dane są modyfikowane, ale waga nie jest. Musisz więc dokonać ponownego obliczenia ręcznie, jeśli dane często się zmieniają. – Harriv

2

Chciałem zaktualizować tę odpowiedź dla nowszego firebirda. tutaj jest zaktualizowany dsql.

SET TERM^; 
CREATE OR ALTER PROCEDURE NEW_PROCEDURE 
AS 
DECLARE VARIABLE S VARCHAR(300); 
begin 
    FOR select 'SET statistics INDEX ' || RDB$INDEX_NAME || ';' 
    FROM RDB$INDICES 
    WHERE RDB$INDEX_NAME <> 'PRIMARY' INTO :S 
    DO BEGIN 
    EXECUTE STATEMENT :s; 
    END 
end^ 
SET TERM ;^

GRANT EXECUTE ON PROCEDURE NEW_PROCEDURE TO SYSDBA;